13 Stimmen

Was ist der schnellste Weg, um eine 10 GB große Datei von der Festplatte zu lesen?

Wir müssen verschiedene Arten von Nachrichten lesen und zählen / ausführen einige Statistiken über eine 10 GB große Textdatei, z.B. eine FIX Motor Protokoll. Wir verwenden Linux, 32-Bit, 4 CPUs, Intel, programmieren in Perl, aber aber die Sprache ist nicht wirklich wichtig.

Ich habe einige interessante Tipps im Buch von Tim Bray gefunden WideFinder-Projekt . Wir haben jedoch festgestellt, dass die Verwendung von Memory Mapping von Natur aus durch die 32-Bit-Architektur begrenzt ist.

Wir haben versucht, mehrere Prozesse zu verwenden, was zu funktionieren scheint schneller, wenn wir die Datei parallel mit 4 Prozessen auf auf 4 CPUs. Das Hinzufügen von Multi-Threading verlangsamt es, vielleicht wegen der Kosten für die Kontextumschaltung. Wir haben versucht, die Größe des Threadpools zu ändern, aber das ist immer noch langsamer als einfache Multiprozess-Version.

Der Teil der Speicherzuordnung ist nicht sehr stabil, manchmal ist er dauert 80 Sekunden und manchmal 7 Sekunden bei einer 2 GB großen Datei, vielleicht wegen Seitenfehlern oder etwas, das mit der Nutzung des virtuellen Speichers zusammenhängt. Wie auch immer, Mmap kann nicht über 4 GB auf einem 32-Bit-System skalieren. Architektur.

Wir haben Perl's IPC::Mmap y Sys::Mmap . Nachgeschaut auch mit Map-Reduce beschäftigt, aber das Problem ist wirklich I/O gebunden, die Verarbeitung selbst ist ausreichend schnell.

Daher haben wir uns entschlossen, die grundlegende E/A zu optimieren, indem wir die Puffergröße, Typ usw. zu optimieren.

Kennt jemand ein bestehendes Projekt, bei dem diese Problem in irgendeiner Sprache/Plattform effizient gelöst wurde auf einen nützlichen Link hinweisen oder eine Richtung vorschlagen?

1voto

Hmmm, aber was ist falsch mit dem read()-Befehl in C? Normalerweise hat er ein 2GB-Limit, also rufen Sie ihn einfach 5 Mal hintereinander auf. Das sollte ziemlich schnell sein.

1voto

Keith Randall Punkte 22725

Wenn Sie an die E/A-Beschränkung gebunden sind und Ihre Datei auf einer einzigen Festplatte liegt, gibt es nicht viel zu tun. Ein einfacher linearer Single-Thread-Scan über die gesamte Datei ist der schnellste Weg, um die Daten von der Festplatte zu bekommen. Die Verwendung großer Puffergrößen könnte ein wenig helfen.

Wenn Sie den Schreiber der Datei davon überzeugen können, die Datei auf mehrere Festplatten/Maschinen zu verteilen, könnten Sie darüber nachdenken, den Leser zu multithreaden (ein Thread pro Lesekopf, wobei jeder Thread die Daten von einem einzelnen Stripe liest).

0voto

pokrate Punkte 3804

In der Aufgabenstellung ist nicht angegeben, ob die Reihenfolge wirklich wichtig ist oder nicht. Also, teilen Sie die Datei in gleiche Teile, z. B. je 1 GB, und da Sie mehrere CPUs verwenden, sind mehrere Threads kein Problem. Lesen Sie also jede Datei mit einem separaten Thread und verwenden Sie einen Arbeitsspeicher mit einer Kapazität von > 10 GB, dann würde der gesamte Inhalt im Arbeitsspeicher gespeichert und von mehreren Threads gelesen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X