Was wäre eine ideale Puffergröße? [duplicate]

Lesezeit: 6 Minuten

Benutzer-Avatar
Baruch

Mögliches Duplikat:

Wie bestimmen Sie die ideale Puffergröße bei der Verwendung von FileInputStream?

Beim Lesen von Rohdaten aus einer Datei (oder einem beliebigen Eingabestrom) mit einem der C++-Programme istream Familie read() oder Cs fread(), muss ein Puffer bereitgestellt werden und eine Anzahl, wie viele Daten gelesen werden sollen. Die meisten Programme, die ich gesehen habe, scheinen willkürlich eine Potenz von 2 zwischen 512 und 4096 gewählt zu haben.

  1. Gibt es einen Grund, warum es eine Potenz von 2 sein muss / sollte, oder ist dies nur die natürliche Neigung des Programmierers zu Potenzen von 2?
  2. Was wäre die “ideale” Zahl? Mit “ideal” meine ich, dass es am schnellsten wäre. Ich nehme an, es müsste ein Vielfaches der Puffergröße des zugrunde liegenden Geräts sein? Oder vielleicht vom Puffer des zugrunde liegenden Stream-Objekts? Wie würde ich überhaupt bestimmen, wie groß diese Puffer sind? Und wenn ich das tue, würde die Verwendung eines Vielfachen davon eine Geschwindigkeitssteigerung gegenüber der Verwendung der genauen Größe bewirken?

BEARBEITEN

Die meisten Antworten scheinen zu sein, dass es zur Kompilierzeit nicht bestimmt werden kann. Ich finde es in Ordnung, es zur Laufzeit zu finden.

  • Ich glaube, die Puffergröße hängt entweder vom Compiler oder vom Computer ab (sorry, ich weiß nicht, welcher oder vielleicht beides). Der einzige Weg, dies herauszufinden, besteht darin, es durch Einlesen verschiedener Datengrößen zu versuchen. Es sollte schnell sein, also mach es 100 Mal und nimm den Durchschnitt. Es sollte nicht eine Gerade sein. Ich vermute, Sie sollten es bemerken, wenn Sie den Punkt überschritten haben, an dem ein weiterer Datenpuffer gelesen werden muss. (Alternativ können Sie den Quellcode von C/C++ durchsuchen …)

    – Strahl

    22. Mai 2012 um 8:33 Uhr

  • Machen Sie im Zweifelsfall immer eine Zweierpotenz Ihrer Puffergröße. Andere Programmierer werden denken, dass Sie es aus einem cleveren Grund getan haben. 😉

    – Frerich Raabe

    22. Mai 2012 um 8:40 Uhr

  • Re edit: Laufzeit hilft nicht viel. Die Profilerstellung muss zur Entwicklungszeit erfolgen, es sei denn, Sie können sich bei jedem Start Ihres adaptiven gepufferten Codes extreme „Aufwärmläufe“ mit vielen Daten leisten.

    – Jirka Hanika

    23. Mai 2012 um 12:21 Uhr

Benutzer-Avatar
Ravi

QUELLE:
Wie bestimmen Sie die ideale Puffergröße bei der Verwendung von FileInputStream?

Die optimale Puffergröße hängt von mehreren Faktoren ab: Blockgröße des Dateisystems, Größe des CPU-Cache und Cache-Latenz.

Die meisten Dateisysteme sind so konfiguriert, dass sie Blockgrößen von 4096 oder 8192 verwenden. Wenn Sie Ihre Puffergröße so konfigurieren, dass Sie ein paar Bytes mehr als den Plattenblock lesen, können die Operationen mit dem Dateisystem theoretisch äußerst ineffizient sein (d.h. wenn Sie Ihren Puffer so konfiguriert haben, dass er 4100 Bytes gleichzeitig liest, würde jeder Lesevorgang 2 Blocklesevorgänge durch das Dateisystem erfordern). Wenn sich die Blöcke bereits im Cache befinden, zahlen Sie am Ende den Preis für RAM -> L3/L2-Cache-Latenz. Wenn Sie Pech haben und die Blöcke noch nicht im Cache sind, zahlen Sie auch den Preis der Disk->RAM-Latenz.

Aus diesem Grund sehen Sie die Größe der meisten Puffer als Potenz von 2 und im Allgemeinen größer als (oder gleich) der Plattenblockgröße. Dies bedeutet, dass einer Ihrer Stream-Lesevorgänge zu mehreren Blocklesevorgängen auf der Festplatte führen kann – diese Lesevorgänge verwenden jedoch immer einen vollständigen Block – keine verschwendeten Lesevorgänge.

Dies sicherzustellen führt typischerweise auch zu anderen leistungsfreundlichen Parametern, die sowohl das Lesen als auch die nachfolgende Verarbeitung beeinflussen: Datenbusbreitenausrichtung, DMA-Ausrichtung, Speicher-Cache-Zeilenausrichtung, ganze Anzahl virtueller Speicherseiten.

  1. Zumindest in meinem Fall geht man davon aus, dass das zugrunde liegende System einen Puffer verwendet, dessen Größe ebenfalls eine Zweierpotenz ist, also ist es am besten, es zu versuchen und abzugleichen. Ich denke, heutzutage sollten Puffer etwas größer gemacht werden, als “die meisten” Programmierer dazu neigen, sie zu machen. Ich würde zum Beispiel eher 32 KB als 4 nehmen.
  2. Es ist leider sehr schwer im Voraus zu wissen. Dies hängt beispielsweise davon ab, ob Ihre Anwendung E/A- oder CPU-gebunden ist.

  • Vorher brauche ich das nicht. Ich finde es in Ordnung, es zur Laufzeit zu finden

    – Baruch

    22. Mai 2012 um 8:31 Uhr


  1. Ich denke, dass es meistens nur darum geht, eine “runde” Zahl zu wählen. Wenn Computer mit Dezimalzahlen arbeiten würden, würden wir wahrscheinlich 1000 oder 10000 statt 1024 oder 8192 wählen. Es gibt keinen sehr guten Grund.

Ein möglicher Grund ist, dass Festplattensektoren normalerweise 512 Bytes groß sind, sodass das Lesen eines Vielfachen davon effizienter ist, vorausgesetzt, dass alle Hardwareschichten und das Caching dazu führen, dass der Low-Level-Code diese Tatsache tatsächlich effizient nutzen kann. Was es wahrscheinlich nicht kann, es sei denn, Sie schreiben einen Gerätetreiber oder führen einen ungepufferten Lesevorgang durch.

Mir ist kein Grund bekannt, dass es eine Zweierpotenz sein muss. Sie sind durch die Puffergröße eingeschränkt, die innerhalb von max size_t aber das wird wohl kein problem sein.

Natürlich ist es umso besser, je größer der Puffer ist, aber dies ist offensichtlich nicht skalierbar, so dass Überlegungen zu den Systemressourcen entweder zur Kompilierzeit oder vorzugsweise zur Laufzeit berücksichtigt werden müssen.

Benutzer-Avatar
Guffa

1 . Gibt es einen Grund, warum es eine Potenz von 2 sein muss / sollte, oder ist dies nur die natürliche Neigung des Programmierers zu Potenzen von 2?

Nicht wirklich. Es sollte wahrscheinlich etwas sein, das sogar in die Größe der Datenbusbreite passt, um das Kopieren des Speichers zu vereinfachen, also wäre alles, was durch 16 teilbar ist, mit der aktuellen Technologie gut. Die Verwendung einer Potenz von 2 macht es wahrscheinlich, dass es mit jeder zukünftigen Technologie gut funktioniert.

2 . Was wäre die “ideale” Zahl? Mit “ideal” meine ich, dass es am schnellsten wäre.

Am schnellsten wäre so viel wie möglich. Sobald Sie jedoch ein paar Kilobyte überschreiten, haben Sie einen sehr kleinen Leistungsunterschied im Vergleich zu der Menge an Speicher, die Sie verwenden.

Ich nehme an, es müsste ein Vielfaches der Puffergröße des zugrunde liegenden Geräts sein? Oder vielleicht vom Puffer des zugrunde liegenden Stream-Objekts? Wie würde ich überhaupt bestimmen, wie groß diese Puffer sind?

Sie können die Größe der zugrunde liegenden Puffer nicht wirklich kennen oder sich darauf verlassen, dass sie gleich bleiben.

Und wenn ich das tue, würde die Verwendung eines Vielfachen davon eine Geschwindigkeitssteigerung gegenüber der Verwendung der genauen Größe bewirken?

Einige, aber sehr wenig.

Benutzer-Avatar
Rup

Ich denke, die ideale Größe des Puffers ist die Größe eines Blocks auf Ihrer Festplatte, damit er beim Speichern oder Abrufen von Daten von der Festplatte Ihrem Puffer richtig zugeordnet werden kann.

1373320cookie-checkWas wäre eine ideale Puffergröße? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy