c ++ wahnsinniger Speicherverbrauch bei großer Datei

7

Ich lade eine 10-GB-Datei in den Speicher und finde heraus, dass selbst dann, wenn ich einen zusätzlichen Overhead wegnehme und die Daten in nichts als einem Array abspeicherte, immer noch 53 GB RAM benötigt. Das scheint mir verrückt zu sein, da ich einige der Textdaten in Longs umwandele, die weniger Platz benötigen und den Rest in char * umwandeln, das den gleichen Raum wie eine Textdatei einnehmen sollte. Ich habe ungefähr 150 Millionen Datenzeilen in der Datei, die ich zu laden versuche. Gibt es einen Grund, warum dies so viel Ram aufnehmen sollte, wenn ich es so lade, wie ich es unten mache?

Hier gibt es drei Dateien, eine fileLoader-Klasse und ihre Header-Datei und ein main, das sie einfach ausführt. Um einige Fragen zu beantworten: OS ist UBUNTU 12.04 64bit Dies ist auf einem machien mit 64GB RAM und einem SSD-hd, dass ich 64GB Swap-Speicherplatz für RAM bereitstellen Ich lade alle Daten auf einmal wegen der Notwendigkeit für die Geschwindigkeit. Es ist kritisch für die Anwendung. Alle Sortier-, Indexierungs- und viele datenintensive Arbeiten werden auf der GPU ausgeführt. Der andere Grund ist, dass das Laden aller Daten auf einmal es viel einfacher machte, den Code zu schreiben. Ich brauche mir keine Gedanken über indizierte Dateien und Zuordnungen zu Orten in einer anderen Datei zu machen.

Hier ist die Header-Datei:

%Vor%

Hier ist die CPP-Datei

%Vor%

Hier ist die Datei mit meiner Hauptfunktion:

%Vor%

Hier ist ein Beispiel für die Daten, die ich lade:

%Vor%     
flip 10.06.2014, 20:20
quelle

2 Antworten

28

Sie ordnen jeder Zeile neun Speicherblöcke zu, sodass Sie insgesamt 1350 Millionen Speicherbereiche zuweisen. Diese Zuweisungen haben einen gewissen Overhead, normalerweise mindestens doppelt so groß wie ein Zeiger, möglicherweise sogar mehr. Auf einer 64-Bit-Maschine sind das bereits 16 Byte, also 21,6 GB Overhead.

Darüber hinaus erhalten Sie den Overhead der Heapfragmentierung und -ausrichtung: Selbst wenn Sie nur eine Zeichenfolge darin speichern, muss der Zuordner die Speicherzuweisungen so ausrichten, dass Sie die größtmöglichen Werte darin speichern können, ohne auszulösen Fehlausrichtung. Die Ausrichtung hängt möglicherweise von der Vektoreinheit Ihrer CPU ab, die sehr signifikante Ausrichtungen erfordern kann. Die 16-Byte-Ausrichtung ist nicht ungewöhnlich.

Bei der Berechnung mit 16 Byte Allokationsaufwand und 16 Byte Ausrichtung erhalten wir Zuweisungen von 43,2 GB ohne die ursprünglichen Daten . Mit den Originaldaten liegt diese Berechnung bereits sehr nahe an Ihrer Messung.

    
cmaster 10.06.2014, 20:45
quelle
3

Jedes dieser Objekte und Zeichenfolgen, die Sie erstellen, hat einen individuellen Speicherverwaltungsaufwand. So laden Sie die Zeichenfolge "0" aus Spalte 2, abhängig von Ihrem Speichermanager, es dauert wahrscheinlich zwischen zwei und vier vollständige Wörter (könnte mehr sein). Nennen Sie es 16 bis 32 Bytes Speicher, um eine Ein-Byte-Zeichenfolge zu speichern. Dann laden Sie die "1" aus Spalte 3. Und so weiter.

    
DrC 10.06.2014 20:29
quelle