Frage

Ich bin derzeit an einem Projekt arbeite mit externer merge-Art mit Ersatz-Auswahl und k-Wege-Zusammenführung. Ich habe das Projekt in C ++ [läuft auf Linux] implementiert. Es ist sehr einfach und jetzt geht es nur mit fester Größe Aufzeichnungen.

Für das Lesen und Schreiben von I Verwendung (i / o) fstream Klassen. Nachdem das Programm für einige Iterationen ausführen, bemerkte ich, dass

  • I / O-Leseblocks für Anfragen der Größe mehr als 4K (typische Blockgröße). Infact gibt Performance Puffergrößen von mehr als 4K Ursachen zu verringern.
  • Die Ausgabeoperationen scheint nicht notwendig Pufferung, linux schien darauf zu achten Ausgabe zu puffern. Also habe ich ein Schreiben (Aufzeichnung) ausgeben, anstatt spezielle Puffer von Schreibvorgängen zu erhalten und sie dann auf einmal mit Schreib Ausspülen (Aufzeichnungen []).

Aber die Leistung der Anwendung scheint nicht groß zu sein. Wie kann ich die Leistung verbessern? Soll ich spezielle I / O-Threads halten Leseblöcke zu kümmern oder gibt es bestehende C ++ Klassen diese Abstraktion bietet schon? (So etwas wie BufferedInputStream in Java)

War es hilfreich?

Lösung

Eine solche Hochleistungs-I / O wird am einfachsten mit mmap getan. Dies gibt den Kern viel mehr Freiheit I / O und Zeitplan CPU-Zeit für Ihre Anwendung auszuführen. Zum Beispiel, wenn Sie in 1 MB mit ifstream lesen, kann der Kernel nur zurückkehren, wenn alle Daten gelesen werden. Aber mit mmap () kann die Daten zurückgegeben werden inkrementell sobald sie verfügbar sind.

Allerdings sollten Sie verstehen, wie das passiert. Nur weil die Daten im RAM zu sein scheinen, bedeutet nicht, dass Sie es als Zufall behandeln sollten zuzugreifbar. Füttern Sie es nicht zu std::sort. Dies wird zufällig Teile des mmap'ed Bereich berühren, so dass Seitenfehler rechts und Mitte links. Als Ergebnis, werden Sie suchen schwere Scheibe verursachen die zufälligen Seitenfehler zu beheben. Stattdessen mmap() zwei Eingänge und sie verschmelzen. Da der mmap Befehl den Kernel gesagt, welche Daten Sie in Zukunft benötigen, wird der Kernel Sie Daten so schnell füttern, wie es kann, und Ihre Mergesort Willen Seitenfehler (das heißt Stall), wenn sie vorübergehend aus Daten.

Andere Tipps

Schauen Sie sich die C Low-Level-IO-Bibliothek. http://www.linuxtopia.org/online_books/programming_books/gnu_libc_guide/ Low_002dLevel-I_002fO.html oder ftp://ftp2.developpez.be/ developps / linux / alp / alp-APB-Low-Level-io.pdf

In Fenster vor langer Zeit ich habe einige IO 10-mal schneller mit der Low-Level-IO offen laufen als fopen.

Vielleicht werden Sie nicht die gleiche Leistung profitieren, ich weiß, dass es etwas sein wird.

Streams sind für ihre Performance-Probleme bekannt im Vergleich zu Normal-C I / O. In der Tat wirken sie als ‚leicht zu bedienen und eignet sich für unterschiedliche Situationen‘, aber es fehlt in der Leistung. Was würde ich in Ihrer Situation zu tun ist die Umstellung auf C-Stil I / O, Profilieren und dann handelt auf der Grundlage der Profilierungs Ergebnisse.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top