Verfasst am: 04.07.2012, 14:28
Titel: netcdf - Out of Memory
Hallo Leute ich habe ein netcdf file mit etwa 3.5GB Größe.
Aus diesem File lade ich eine Variable mit 180 x 330 x 8500 Werten. Das laden dauert etwas klappt aber. Bei der weiteren Verarbeitung kommt dann aber out of memory
Code:
function sohip2
%Erzeugung der Variablen im netcdf Format
nccreate('Ergebnis.nc','JMW','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZMW','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
Hs=input('Befehl, Dateiname, Variable:');
% z.B. ncread('SOHIP-V4-1984.nc','hsign');
%Berechnung Jahresmittelwert
%Hs = ncread('test.nc','Hs2');
for xlines = 1:331;
for ylines = 1:181;
Jahresmittel(xlines,ylines)=mean(Hs(xlines,ylines,:));
end end
JM(:,:,z)=(Jahresmittel);
ncwrite('Ergebnis.nc','JMW',JM);
for xlines = 1:331;
for ylines = 1:181;
Wintermittel(xlines,ylines) = mean(Winter(xlines,ylines,:));
end end
JZM_W(:,:,z)=(Wintermittel);
ncwrite('Ergebnis.nc','JZMW',JZM_W);
Wenn ich nur 5000 Werte einlese läuft das ganze durch. Ansosnten sagt er in der Zeile
Winter(:,:,1:Winter1laenge)=Winter1;
out of memory.
Habt Ihr ne Idee wie ich das Problem lösen kann ohne die Anzahl der eingelesenen Werte zu verringern?
Ich arbeite mit Matlab 2011b 32 Bit auf einem Remotedesktop von dem ich aktuell nicht weiß mit welcher Rechenleistung er ausgestattet ist. Da es aber der Remoteserver unseres Universitätsrechnezentrums ist gehe ich davon aus, das es doch angemessen sein wird.
Verfasst am: 05.07.2012, 13:34
Titel: Re: netcdf - Out of Memory
Hallo mb005,
Das magische Wort heißt "Pre-allocation":
Code:
function sohip2
...
%Berechnung Jahresmittelwert
%Hs = ncread('test.nc','Hs2');
Jahresmittel = zeros(331, 181); % Pre-allcoate! for xlines = 1:331;
for ylines = 1:181;
Jahresmittel(xlines,ylines)=mean(Hs(xlines,ylines,:));
end end
Wenn man eine Variable in jeder Iteration wachsen läßt, muss Matlab jedes mal Speicherplatz für ein neues Array reservieren und die alten Daten kopieren. Für ein [331x181] Array werden dann nicht 331*181 DOUBLEs reserviert, sondern sum(1:331)*181 und sum(2:331)*181 DOUBLEs kopiert.
Hilft das bereits?
Hallo,
vielen Dank für den Vorschlag.
Leider hilft das Zero Array nicht.
Gibt es noch andere Möglichkeiten der Pre Allocation bzw. Speicherzuweisung?
Zu meinem bedauern wurde mir auch mitgeteil, dass der zur Verfügung stehende Arbeitsspeicher doch nicht wirklich groß ist.
Wie groß konnte ich noch immer nicht in Erfahrung bringen.
Schau dir im Workspace genau an, welche Variablen du hast und wie groß sie sind. Nicht mehr benötigte temporäre Variablen können auch mit CLEAR gelöscht werden.
Hey Leute, eigentlich schien mir das Problem als gelöst und meine Berechnung lief sauber durch, aber nun scheint es wieder ein Memoryproblem zu geben, von dem ich nicht weiß, wie man es schlanker lösen kann.
Hier ein paar Zeilen Quellcode:
Code:
function sohip
%Erzeugung der Variablen im netcdf Format
nccreate('Ergebnis.nc','JM','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_F','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_S','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_H','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_W','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
%Preallocation der Arrays zur Minimierung des Speichebedarfs in den Schleifen
%JM = zeros(331,181,55);
Das Problem entsteht im letzten Absatz. In der vorletzten Zeile steigt Matlab mit Out of Memory aus.
Wenn ich den ausgewählten Bereich verkleinere (auf 2000 Werte) funktioniert es noch. Ab 2030 Werten Out of Memory.
Ich habe versucht sämtliche Dopplungen der Daten zu vermeiden, aber ich muss ja die Rechenoperation durchführen, bevor ich deren Inhalt in die netcdf Datei schreibe oder nicht?
Auch der Versuch in die netcdf zu schreiben ohne die Variable vorher separate zu erzeugen :
Vorschläge:
- die Variable JM löschen
- Hs mit dem Ausschnitt von Hs überschreiben, wenn du du das Original nicht mehr brauchst (siehe Vorschlag zuvor)
Viel dürfte das aber nicht helfen; dann brauchst du entweder mehr Speicher oder musst die Daten "irgendwie" paketweise verarbeiten. Ich kenne mich nicht mit netcdf aus und kann daher nicht sagen wie.
Hey Leute,
also alles Pre-allokieren hat nichts genützt, auch das Vermeiden von doppelt abgelegtem Inhalt reichte nicht aus, out of Memory kam immer wieder.
Aus diesem Grund habe ich das ganze so gelöst, dass nur eine Jahreszeit eingelesen wird, also nur 1/4 des Datenumfangs und dann alle Rechenoperationen mit der Jahreszeit durchgeführt werden und diese dann anschließend gelöscht wird.
So kommt man ohne out of memory durch die Schleifen. Ob das jetzt die beste Lösung ist weiß ich nicht, auf jeden Fall läuft es durch.
Da ich nicht weiß inwiefern die Einlesezeit der 4 Jahreszeiten dem Einlesen des gesamten Jahres entsprict kann ich nichts zur Geschwindigkeitsveränderung der Rechnung durch die AUfteilung sagen.
Naja und wenn es anders nicht funktioniert, nehme ich natürlich auch eine etwas längere Rechenzeit in Kauf.
DAnke für Eure hilfe
Hallo Leute,eigentlich hatte ich ja mein Memory Problem gelöst, aber es ist noch ein neues dazu gekommen.
Zu beginn erzeuge ich die Variablen im net cdf Format, danach die Matritzen für die Schleifendurchgänge und Fülle diese mit Nullen. Anschließend lese ich die recht große Datei ein.
Code:
%Schleifen für die einzelnen Jahre von 1948 - 1999 tic for z=1:52;
y=1947+z;
y=num2str(y);
tic
Hs = ncread(['SOHIP-V4-',y,'.nc'],'hsign');
an dieser Stelle lösche ich Jahresmittel wieder und die Anzahl und der Umfang der Variablen ist wie vor der Jahresmittelwertbestimmung, außer das in JM(:,:,1) keine Nullen mehr stehen sondern errechnete Werte.
Jetzt will ich das Jahresmaximum berechnen und an der Stelle steigt Matlab wieder mit out of memory aus
Nun meine Frage: Wieso funktioniert es für den Jahresmittelwert und nicht für das Jahresmaximum, obwohl der Variablenumfang identisch ist?
Hat einer von Euch ne Idee warum das passiert?
Ich könnte Hs löschen, neu laden und dann das Maximum berechnen, aber das ist ja nu wirklich total blöd oder nich?
du hältst dich vermutlich ganz nah an den Grenzen des verfügbaren Speichers auf. Wenn du wirklich nur MEAN durch MAX ersetzt hast, dann würde das wohl heißen, dass MAX intern temporär aus welchen Gründen auch immer mehr Speicher verbraucht als MEAN.
Eine Lösung für das Problem habe ich nicht, außer mit mehr Speicher oder weniger Daten zu arbeiten.
schreibt nicht das maximum der Matrix b über die dritte Dimension (z-Achse) in eine Matrix mit nur einer z-Ebene, sondern eine Matrix in der selben Dimension wie b gefüllt mit der Zahl 3.
Aus diesem Grund wird eine zweite Matrix von erheblichem Ausmaß erzeugt, was auch der Grund für das Out of Memory an dieser Stelle ist.
Die Lösung des Problems liegt in der richtigen Anwendung von max. Der Befehl sieht dann so aus
Dann gibts auch kein out of memory und alle sind glücklich.
Bis demnächst,
Gruß Marcus
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.