Alle Dinge gleich, was ist der schnellste Weg, um Daten auf der Festplatte in C ++ auszugeben?

7

Ich führe Simulationscode aus, der weitgehend an die CPU-Geschwindigkeit gebunden ist. Ich bin nicht daran interessiert, Daten auf eine Benutzeroberfläche zu übertragen und sie einfach auf der Festplatte zu speichern, während sie berechnet wird.

Was wäre die schnellste Lösung, die den Overhead reduzieren würde? Iostreams? drucken? Ich habe vorher gelesen, dass printf schneller ist. Wird dies von meinem Code abhängen und ist es unmöglich, eine Antwort ohne Profiling zu erhalten?

Dies wird in Windows ausgeführt werden und die Ausgabedaten müssen im Textformat, Tab / Komma getrennt, mit Formatierung / Genauigkeit Optionen für meist Gleitkommawerte sein.

    
mindless.panda 15.06.2011, 22:02
quelle

10 Antworten

3

Mein Gedanke ist, dass Sie das falsche Problem angehen. Warum schreiben Sie große Mengen von Textformaten? Wenn Sie möchten, dass es für Menschen lesbar ist, schreiben Sie ein schnelles Browserprogramm, um die Daten im Binärformat im laufenden Betrieb zu lesen - auf diese Weise kann die Simulationsanwendung schnell binäre Daten ausschreiben und der Browser kann die grunzende Arbeit der Formatierung der Daten bei Bedarf. Wenn Sie ein stats-Paket zum Lesen und Analysieren von Textdaten verwenden, schreiben Sie eines, das Binärdaten eingibt.

    
ravenspoint 04.03.2010, 15:18
quelle
4

Konstruiere (large-ish) Blöcke von Daten, die sequentiell geschrieben werden können und asynchrone IO verwenden.

Genaues Profiling wird schmerzhaft sein, lesen Sie einige Artikel zum Thema: scholar.google.com .

    
Hassan Syed 04.03.2010 14:49
quelle
4

Ich habe sie nicht selbst benutzt, aber ich habe gehört, dass speicherprogrammierte Dateien dem OS die besten Optimierungsmöglichkeiten bieten.

Bearbeiten: Frage und Wikipedia-Artikel zu Memory-Mapped-Dateien - beide erwähnen Leistungsvorteile.

    
AshleysBrain 23.05.2017 12:07
quelle
3

Scott Meyers 'effektiveres C ++, Punkt 23 "Überlegen Sie alternative Bibliotheken" schlägt vor, stdio über iostream zu verwenden, wenn Sie Geschwindigkeit gegenüber Sicherheit und Erweiterbarkeit bevorzugen. Es lohnt sich zu überprüfen.

    
stefaanv 04.03.2010 14:49
quelle
2

Der schnellste Weg ist, was für Ihre spezielle Anwendung am schnellsten ist, wenn sie auf dem typischen Zielbetriebssystem und der Zielhardware ausgeführt wird. Das einzig Vernünftige ist es, mehrere Ansätze auszuprobieren und zeitlich zu bestimmen. Sie benötigen wahrscheinlich kein vollständiges Profil und die Übung sollte nur ein paar Stunden dauern. Ich würde testen, in dieser Reihenfolge:

  • normale C ++ - Stream-E / A
  • normaler Stream I / O mit ostream :: write ()
  • Verwendung der C-I / O-Bibliothek
  • Verwendung von Systemaufrufen wie write ()
  • asynch I / O

Und ich würde aufhören, wenn ich eine Lösung fand, die schnell genug war.

    
anon 04.03.2010 15:19
quelle
2

Textformat bedeutet, dass es für den menschlichen Verzehr bestimmt ist. Die Geschwindigkeit, mit der Menschen lesen können, ist weit, viel niedriger als die Geschwindigkeit irgendeiner vernünftigen Ausgabemethode. Da ist irgendwo ein Widerspruch. Ich vermute, die "Ausgabe muss Textformat sein".

Daher glaube ich, dass das korrekte ist, um binär auszugeben, und einen separaten Viewer bereitzustellen, um einzelne Einträge in lesbaren Text zu konvertieren. Formatierung im Viewer muss nur so schnell sein, wie die Leute lesen können.

    
MSalters 04.03.2010 16:37
quelle
1

Öffnen Sie die Datei im Binärmodus und schreiben Sie "unformatierte" Daten auf die Disc.

%Vor%

BEARBEITEN: Das OP hat hinzugefügt, dass "Ausgabedaten im Textformat vorliegen müssen, egal ob Tab oder Komma getrennt sind." Einschränkung.

Wenn Ihre Anwendung an die CPU gebunden ist, ist die Formatierung der Ausgabe ein Overhead, den Sie nicht benötigen. Binäre Daten sind viel schneller zu schreiben und zu lesen als ascii, sind kleiner auf der Platte (z. B. gibt es weniger Byte mit binären als mit ASCII), und weil sie kleiner sind, ist es schneller, sich in einem Netzwerk zu bewegen (einschließlich eines gemounteten Netzwerks) Dateisystem). Alle Indikatoren weisen auf eine binäre Gesamtoptimierung hin.

Das Anzeigen der Binärdaten kann nach dem Lauf mit einem einfachen Dienstprogramm erfolgen, das die Daten in dem gewünschten Format in Ascii ablegt. Ich würde einige Versionsinformationen zu den resultierenden Binärdaten hinzufügen, um sicherzustellen, dass Änderungen im Datenformat im Dump-Dienstprogramm gehandhabt werden können.

Von binär zu ascii zu wechseln und dann über die relative Leistung von printf gegenüber iostreams zu streiten, ist wahrscheinlich nicht die beste Verwendung Ihrer Zeit.

    
Stan Graves 04.03.2010 19:09
quelle
1

Mapping der Datei in den Speicher (zB mit einer Memory Mapped File ), dann nur memcopy -ing Daten es gibt eine wirklich schnelle Art zu lesen / schreiben.

Sie können mehrere Threads / Kerne verwenden, um in die Daten zu schreiben, und das Betriebssystem / Kernel synchronisiert die Seiten mit der gleichen Art von Routinen, die für den virtuellen Speicher verwendet werden , mehr oder weniger.

Hauptsächlich sollte es einige zusätzliche Kopien / Puffer im Speicher geben, wenn Sie dies tun. Die Schreibvorgänge werden von Interrupts abgefangen und nach dem Schreiben einer Seite zur Festplattenwarteschlange hinzugefügt.

    
Macke 24.08.2012 12:18
quelle
0

Der schnellste Weg ist completion-based asynchronous IO.

Indem dem Betriebssystem eine Menge von Daten zum Schreiben gegeben wird, die es bei der Rückkehr des Aufrufs nicht tatsächlich geschrieben hat, kann das OS es neu anordnen, um die Schreibleistung zu optimieren.

Die API hierfür ist betriebssystemspezifisch: Unter Linux heißt sie AIO ; Unter Windows nennt man es Completion Ports .

    
Will 04.03.2010 14:47
quelle
0

Eine schnelle Methode besteht darin, doppelte Pufferung und mehrere Threads (mindestens zwei) zu verwenden.

Ein Thread ist verantwortlich für das Schreiben von Daten auf die Festplatte. Diese Aufgabe prüft den Puffer und wenn nicht leer (oder vielleicht eine andere Regel) beginnt, auf die Festplatte zu schreiben.

Der andere Thread schreibt formatierten Text in den Puffer.

Ein Leistungsproblem bei Festplatten ist die Zeit, die benötigt wird, um die Geschwindigkeit zu erhöhen und den Kopf an der richtigen Stelle zu positionieren. Um dies zu vermeiden, ist es das Ziel, kontinuierlich auf die Festplatte zu schreiben, damit sie nicht aufhört. Dies ist schwierig und kann Dinge beinhalten, die außerhalb des Programmumfangs liegen (wie andere Programme, die gleichzeitig ausgeführt werden). Je größer der Datenblock ist, der auf die Festplatte geschrieben wird, desto besser.

Ein weiterer Dorn ist es, leere Slots auf der Festplatte zu finden, um die Daten zu speichern. Eine fragmentierte Festplatte wäre langsamer als ein formatiertes oder defragmentiertes Laufwerk.

Wenn die Portabilität kein Problem darstellt, können Sie Ihr Betriebssystem auf einige APIs überprüfen, die Blockschreiben auf die Festplatte schreiben. Oder Sie können tiefer gehen und die API verwenden, die direkt auf das Laufwerk schreibt.

Vielleicht möchten Sie auch, dass Ihr Programm seine Priorität ändert, damit es eine der wichtigsten laufenden Aufgaben ist.

    
Thomas Matthews 04.03.2010 17:22
quelle

Tags und Links