2016-08-02 39 views
0

Ich habe ein Programm geschrieben, das Daten liest/schreibt (eine Infile und eine Outfile öffne, einen Teil von Infile lese, dann verarbeite, dann in outfile schreibe und diesen Zyklus wiederholt), mit I/O-Wert etwa 200M/s insgesamt. Sie haben jedoch den größten Teil der Laufzeit im Status D, was bedeutet, dass sie auf E/A warten (wie in der Abbildung gezeigt) 1. Ich verwendete dd überprüfen Schreibgeschwindigkeit in meinem System, das ist etwa 1,8 G/s.So vermeiden Sie Programme im Status D

enter image description here

Sind meine Programme ineffizient? Oder meine Festplatte haben Probleme? Wie kann ich damit umgehen?

+3

Bis Sie einen ordnungsgemäßen Test der Lese- und Schreibleistung für Ihre Festplatten durchgeführt haben, haben Sie keine Grundlage, irgendwelche Rückschlüsse auf die Leistung Ihrer Festplatten zu ziehen. Mit "richtigem Test" meine ich die Ausführung eines der gut etablierten und leicht im Internet verfügbaren Benchmarks für diesen Zweck. Ich würde sicherlich nicht die Schlussfolgerung ziehen, dass Ihr Programm ineffizient ist - es kann einfach nicht genug I/O tun, um die (theoretische) maximale Übertragungsrate Ihrer Platte (n) zu erreichen. Oder die Mischung aus Lese- und Schreibvorgängen verhindert möglicherweise, dass die maximale Übertragungsrate erreicht wird. –

+0

Sie benötigen eine Methode, um Metriken darüber zu erhalten, was sie tun und was nicht. Das ist entweder Debug-Zeilen im Code, oder so etwas wie Intel Inspektor, etc. So könnten Sie I/O-Timer haben und Timer berechnen ... Wenn Sie schreiben oder lesen kleine Blöcke dann könnte es genug Prozesse bekommen, um die Dinge zu verlangsamen. Es ist nicht ungewöhnlich, alle I/O-Vorgänge über einen einzigen Thread auszuführen und die Arbeit über die Knoten zu verteilen. Möglicherweise müssen Sie ein kleineres Problem mit 1 oder 2 Threads lösen, um das Problem zu beheben. Ich vermute einen Race Condition ... oder eine Datei, die nicht richtig schließt/spült. – Holmz

Antwort

0

Wenn Sie ifort verwenden, müssen Sie explizit gepufferte E/A verwenden. Markieren Sie mit -assume buffered_io beim Kompilieren oder setzen Sie buffered='yes' in der open Anweisung.

Wenn Sie gfortran verwenden, ist dies der Standard, also muss es ein anderes Problem geben.

bearbeiten

Ich kann hinzufügen, dass je nachdem, wie man lesen und schreiben, um die Daten, kann die meisten Zeit verbracht wird Parsen, dh ASCII-Zeichen 123 usw. Decodierung und die Basis 10-2 zu ändern, bis es maschinenlesbare Daten; dann beim Schreiben das Gegenteil tun. Dies ist der Fall, wenn Sie Ihren Code wie folgt konstruieren:

real :: vector1(10) 

do 
    read(5,*) vector1 !line has 10 values 
    write(6,*) vector1 
enddo 

Wenn Sie die folgende Stelle tun, wird es viel schneller sein:

character(1000) :: line1 ! use enough characters so the whole line fits 

do 
    read(5,'(A)') line1 
    write(6,'(A)') line1 
enddo 

Jetzt sind Sie gerade, ohne auch nur ascii durch das Programm Pumpen zu wissen, ob seine Ziffern oder vielleicht "ääåö (=) &/&%/(¤%/& Rhgksbks --- 31". Mit diesen Änderungen glaube ich Ihnen den max Ihre Plattengeschwindigkeit erreichen sollten.

Beachten Sie auch, dass da ist ein Schreibe Cache in den meisten Laufwerken, was schneller ist als die Lese-/Schreibgeschwindigkeiten der Platte, was bedeutet, dass du zuerst von der Lesegeschwindigkeit gedrosselt wirst und nach dem Auffüllen des Schreibcache durch die Schreibgeschwindigkeit gedrosselt wirst, die normalerweise niedriger ist als die Geschwindigkeit lesen.