Warum kann 'dd' schneller von einer Pipe lesen als mein eigenes Programm mit ifstream?

8

Ich habe zwei Programme, die Daten über Linux-Pipes untereinander austauschen (benannt oder nicht). Ich muss eine Übertragungsrate von ~ 2600 MB / s zwischen den beiden Programmen erreichen, sehe aber derzeit eine langsamere Rate von ca. 2200 MB / s. Allerdings habe ich festgestellt, dass, wenn ich stattdessen meinen zweiten Prozess durch "dd" ersetze, die Übertragungsrate auf über 3000 MB / s springt. Gibt es etwas über die Art und Weise, wie mein Programm von der Pipe liest, die weniger effizient ist als die Art, wie 'dd' es tut? Was kann ich tun, um diesen Durchsatz zu verbessern? Ist 'ifstream' von Natur aus langsamer als andere Methoden zum Lesen binärer Daten aus der Pipe?

Um die zwei Szenarien zusammenzufassen:

  

Szenario 1:

     

Programm 1 - & gt; [Named Pipe] - & gt; Programm 2

     

liefert ~ 2200 MB / s Übertragungsrate

     

Szenario2:

     

Programm 1 - & gt; [Named Pipe] - & gt; 'dd if = Schreibpinnenname = / dev / null bs = 8M'

     

liefert ~ 3000 MB / s Übertragung   bewerten.

Hier ist die Art und Weise, wie mein Programm 2 aktuell von pipe liest:

%Vor%

Aktualisierung:

Ich habe jetzt versucht, 'read (fd, & amp; buffer [0], 8 * 1024 * 1024)' anstelle von istream zu verwenden, schien eine milde Verbesserung zu zeigen (aber nicht so viel wie dd)

Ich habe auch versucht, Stream- & gt; rdbuf () - & gt; sgetn (& amp; Puffer [0], 8 * 1024 * 1024) anstelle von Stream & gt; read (), was nicht geholfen hat.

    
KyleL 27.03.2013, 18:20
quelle

2 Antworten

3

Der Unterschied scheint auf die Verwendung eines Arrays anstelle von std :: vector zurückzuführen zu sein, an das ich immer noch schwer glauben kann. Meine zwei Sätze Code sind unten zum Vergleich gezeigt. Der erste kann aus Programm 1 mit einer Rate von etwa 2500 MB / s aufnehmen. Der zweite kann mit einer Rate von 3100 MB / s aufnehmen.

Programm 1 (2500 MB / s)

%Vor%

Programm 2 (3100 MB / s)

%Vor%

Beide werden mit -O3 mit gcc Version 4.4.6 kompiliert. Wenn irgendjemand den Grund dafür erklären könnte, wäre ich sehr interessiert (da ich std :: vector im Grunde als einen Wrapper um ein Array verstehe).

Bearbeiten : Ich habe gerade Programm 3 getestet, das ifstream verwendet und mit 3000 MB / s läuft. Es scheint also, dass die Verwendung von ifstream anstelle von "read ()" eine sehr geringe Leistungsverschlechterung mit sich bringt. Viel weniger als der Treffer aus der Verwendung von std :: vector.

Programm 3 (3000 MB / s)

%Vor%

Bearbeiten 2:

Ich habe den Code von Programm 2 so geändert, dass er mallorquinierten Speicher anstelle von Speicher auf dem Stack verwendet, und die Leistung wurde verringert, um der Vektorleistung zu entsprechen. Danke, ipc, dass du mich auf diese Seite gebracht hast.

    
KyleL 27.03.2013, 20:09
quelle
1

Dieser Code wurde mit g++ -Ofast :

kompiliert %Vor%

funktioniert überhaupt nicht so schlecht.

%Vor%

Sie müssen bedenken, dass std::cout einen Puffer mit stdout teilt, was sehr zeitaufwendig ist, wenn er nicht ausgeschaltet ist. Also rufe std::ios_base::sync_with_stdio(false); auf, wenn du Geschwindigkeit willst und nicht die Eingabe-Ausgabemethoden von C verwenden willst (die sowieso langsamer sind).

Verwenden Sie auch für die schnelle und schnelle Eingabe / Ausgabe in C ++ die Methoden von streambuf , die von rdbuf() erhalten wurden.

    
ipc 27.03.2013 18:53
quelle

Tags und Links