2012-06-21 11 views
7

Ich arbeite daran, ein in Fortran geschriebenes Analyseprogramm für Flüssigkeitsströmung und Wärmeübertragung zu optimieren. Während ich versuche, größere und größere Mesh-Simulationen auszuführen, stoße ich auf Speicherbeschränkungsprobleme. Das Netz ist jedoch nicht so groß. Nur 500.000 Zellen und kleine Erdnüsse lassen einen typischen CFD-Code laufen. Selbst wenn ich 80 GB Speicher für mein Problem anfordere, stürzt es aufgrund unzureichenden virtuellen Speichers ab.Fortran-Array-Speicherverwaltung

Ich habe ein paar Vermutungen darüber, welche Arrays sind all diese Speicher. Einer wird insbesondere zugeordnet (28801,345600). Korrigieren Sie mich, wenn ich falsch in meinen Berechnungen bin, aber ein Array mit doppelter Genauigkeit ist 8 Bits pro Wert. Also wäre die Größe dieses Arrays 28801 * 345600 * 8 = 79,6 GB?

Jetzt denke ich, dass die meisten dieser Array endet Nullen während der Berechnung, so dass wir sie nicht speichern müssen. Ich denke, dass ich den Lösungsalgorithmus ändern kann, um nur die Nicht-Null-Werte zu speichern, um in einem viel kleineren Array zu arbeiten. Ich möchte jedoch sicher sein, dass ich auf die richtigen Arrays schaue, um sie zu verkleinern. Also, zuerst, habe ich die Array-Größe oben korrekt berechnet? Und zweitens, gibt es eine Möglichkeit, Fortran Array-Größen in MB oder GB zur Laufzeit anzeigen zu lassen? Neben dem Ausdruck der meisten speicherintensiven Arrays wäre es interessant zu sehen, wie sich die Speicheranforderungen des Codes während der Laufzeit ändern.

+3

Wie viel tatsächlichen Speicher haben Sie auf der Maschine, auf der Sie das ausführen? Außerdem liegen Sie falsch in Ihrer Annahme * doppelte * Genauigkeit ist 8 Bytes, nicht 8 Bits. Das ergibt etwa 74.16 GB Daten (1024 und nicht 1000). Auch, bin ich richtig in der Annahme, dass Sie tun 4 Tage im Wert von Daten (345600 Sekunden = 60 * 60 * 24 * 4) –

+0

Mike, das wird auf einem Cluster mit bis zu 96 GB Arbeitsspeicher pro Knoten ausgeführt, die ich kann anfordern. Sorry über die Verwirrung von Bytes und Bits und danke, dass du das geklärt hast, aber ich bin da im richtigen Stadion, so dass die Array-Größe definitiv ein Problem ist. Und nein, dass 345600 mit der Anzahl der Zellen im Modellnetz zusammenhängt und nichts mit der Zeit zu tun hat. – rks171

+0

@ user104629: Ein Grund warum könnte sein, dass es kein zusammenhängendes Array von 80 GB Speicher zuordnen kann. –

Antwort

4

Speicherverbrauch ist ein ziemlich vage definiertes Konzept auf Systemen mit virtuellem Speicher. Sie können große Speichermengen zugewiesen (große virtuellen Speichergröße) aber nur ein kleiner Teil davon tatsächlich aktiv verwendet werden (kleine resident Größe - RSS).

Unix-Systeme bieten den Systemaufruf getrusage(2), der Informationen über die Anzahl der Systemressourcen zurückgibt, die von den aufrufenden Thread/process/process children verwendet werden. Insbesondere liefert es den maximalen Wert der RSS, die seit dem Start des Prozesses erreicht wurde. Sie können eine einfache Fortran-Callable-Helfer-C-Funktion schreiben, die getrusage(2) aufrufen und den Wert des ru_maxrss-Felds der rusage-Struktur zurückgeben würde.

Wenn Sie unter Linux laufen und sich nicht um die Portabilität kümmern, können Sie einfach öffnen und lesen von /proc/self/status. Es ist ein einfacher Text Pseudo, dass unter anderem mehrere Zeilen mit Statistiken über den Prozess Nutzung des virtuellen Speichers enthält:

... 
VmPeak:  9136 kB 
VmSize:  7896 kB 
VmLck:   0 kB 
VmHWM:  7572 kB 
VmRSS:  6316 kB 
VmData:  5224 kB 
VmStk:  88 kB 
VmExe:  572 kB 
VmLib:  1708 kB 
VmPTE:  20 kB 
... 

Erläuterung der verschiedenen Felder - here. Sie sind hauptsächlich an VmData, , VmHWM und VmSize interessiert. Sie können /proc/self/status als eine normale Datei mit OPEN() öffnen und vollständig in Ihrem Fortran-Code verarbeiten.

Siehe auch, welche Speicherbeschränkungen mit ulimit -a und ulimit -aH festgelegt sind. Sie überschreiten möglicherweise die maximale Größe des virtuellen Festplattenspeichers. Wenn Sie Jobs über einen verteilten Ressourcenmanager (z. B. SGE/OGE, Torque/PBS, LSF usw.) übermitteln, überprüfen Sie, ob Sie genügend Arbeitsspeicher für den Job anfordern.

+1

Cool, danke für den Rat. Die Portabilität spielt für mich keine Rolle, daher denke ich, dass ich mit der Route/proc/self/status gehen werde, um die Speichernutzung zu beobachten. ulimit -a zeigte, dass der virtuelle Speicher unbegrenzt war. Jemand hat mir auch vorgeschlagen, dass DDT und TotalView verwendet werden können, um zu überprüfen, wo in einem Code-Speicher gegessen wird. – rks171

+0

TotalView hat einige erweiterte Debugging-Funktionen, aber ich habe es nicht ausgiebig genutzt. Zumindest jeder Debugger könnte Ihnen anzeigen, wo der Speicherfehler auftritt. Am Ende könnte es etwas anderes sein als die Erschöpfung der Erinnerung. –

+0

Es ist mir gerade in den Sinn gekommen - sind Ihre Cluster-Knoten austauschbar? Wenn ja, könnten Sie den gesamten Systemspeicher erschöpfen und der Linux-OOM-Killer könnte einsteigen ... –