Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!
18.12.2009, 22:44 (Dieser Beitrag wurde zuletzt bearbeitet: 19.12.2009 08:21 von jg.)
ich habe ein SubVi welches bei mir in einer doppelschleife ausgeführt wird. Die innere läuft immer so ca. 250 mal und die Äußere ca.35 mal. Das SubVi bekommt daten als array und verändert bzw. erweitert diese mehrfach.
Mit dem "Performance and Memory Profile" tool habe ich herausgefunden das dort mein Speicher voll läuft, nach ca. 200 Dateien (eine Datei ca 8 Mb) ist der Speicher voll und LV beendet die ausführung.
Habe jetzt schon ein request deallocation eingebaut in das SubVi aber es verhält sich eigentlich wie vorher. Ich glaube LV merkt sich alle zwischenschritte und gibt den Speicher dafür nicht frei, obwohl ich ja nur die Daten am Datenausgang abgreife und dann im main VI als Spreadsheetfile speicher. Ich brauche also die Zwischenschritte nicht im Speicher, weiß aber auch nicht wie ich den Speicherkiller loswerde.
Hoffe ihr versteht was ich meine und habt eine Ahnung was ich da noch machen kann.
' schrieb:Hoffe ihr versteht was ich meine und habt eine Ahnung was ich da noch machen kann.
Also zuerst mal muss ich sagen: Dieses SubVI gehört in mindestens 10 weitere SubVIs aufgeteilt. Da muss ich ja srollen, bis ich alles gesehen habe.
Stimmen die Daten am Ausgang dieses SubVIs mit deinen Erwartungen überein? Wenn ich das auf die Schnelle richtig überblickt habe, wachsen die Längen der Array ständig an. Kann das sein? Das schließe ich aus den vielen "In Array einfügen" in Zusammenhang mit den Schieberegistern.
Die Inhalte der Schieberegister bleiben erhalten! Das SpeicherLöschen nützt für die Schieberegister nichts.
Die vielen ArrayErstellen aufgrund der indizierten Ausgänge an den FOR-Schleifen sind Speicherfresser! Genauso die vielen Elemente ArrayInitialisieren!
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
Danke für die Antwort. Gibts denn da auch Lösungsansätze dafür?
Hast Du selbst auch schon solche Probleme gehabt.
Das SubVI läuft vom Ergebnis her genauso wie es soll. Ich muss noch Daten hinzufügen für weitere Auswertungen mit DIAdem und EXcel.
' schrieb:Gibts denn da auch Lösungsansätze dafür?
Indizierte Ausgänge kann man wie folgt ersetzen: Die Länge des resultierenden Arrays ist ja gleich der Anzahl der Schleifendurchläufe. Also kann man vor der FOR-Schleife ein Array mit ArrayInitialisieren erstellen und dieses Array in der FOR-Schleife mit InArrayErsetzen bearbeiten. Ganz klar, dass bei diesem Verfahren das Array in einem Schieberegister liegen muss. Im Prinzip kann man dieses Verfahren auch für InArrayEinfügen verwenden.
Hinweis:
Bei indizierten Ausgangsarrays muss der MemoryManager im Prinzip bei jedem Schleifendurchlauf das komplette Array + 1 Element neu allozieren. Der Speicherbedarf des vorhergehenden Durchlaufes geht dabei quasi verloren.
Zitat:Hast Du selbst auch schon solche Probleme gehabt.
Nein, nicht in diesen Ausmaßen.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
Ich hab mir's noch mal angekuckt. Ich bin immernoch der Meinung, dass da was nicht passt. Wie ist denn das mit der mittleren FOR-Schleife, die mit den vier Minus-Operationen: Kontrolliere da mal während deiner 250*35 SubVI-Aufrufe die Anzahl der Schleifendurchläufe. Ist die konstant oder soll die tatsächlich ansteigen?
Es gibt dort, wo du das mit dem SpeicherAufräumen gefunden hast, ein sog. Inplacement-Element. Das ist zur Speicheroptimierung gedacht. Ich glaube, dieses Element kannst du brauchen.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
' schrieb:Ich hab mir's noch mal angekuckt. Ich bin immernoch der Meinung, dass da was nicht passt. Wie ist denn das mit der mittleren FOR-Schleife, die mit den vier Minus-Operationen: Kontrolliere da mal während deiner 250*35 SubVI-Aufrufe die Anzahl der Schleifendurchläufe. Ist die konstant oder soll die tatsächlich ansteigen?
Wieso sollte dort die Anzahl der Schleifendurchläufe steigen? Die Schleifendurchläufe hängen doch von der Länge des Eingangsarrays ab.
Dieses ist eigentlich immer 30000 Zeilen lang, also 30000 durchläufe.
' schrieb:Hinweis:
Bei indizierten Ausgangsarrays muss der MemoryManager im Prinzip bei jedem Schleifendurchlauf das komplette Array + 1 Element neu allozieren. Der Speicherbedarf des vorhergehenden Durchlaufes geht dabei quasi verloren.
werden dann dabei die berüchtigten Array-Copy´s angelegt die im Speicher verweilen?
Werd mal anfangen nach und nach alles umzubauen, in der Hoffnung das es dann besser geht.
Das "in place structure" element kann man nicht um Vorschleifen bauen? Habs versucht einfach ringsrum zu ziehen, aber hat mir meine For- Schleife immer außen hin gemacht.
Werd jetzt mal noch probieren ob ich mit den Tipps das Problem in den Griff bekomme...
MfG STG
19.12.2009, 10:13 (Dieser Beitrag wurde zuletzt bearbeitet: 19.12.2009 10:17 von IchSelbst.)
' schrieb:Wieso sollte dort die Anzahl der Schleifendurchläufe steigen? Die Schleifendurchläufe hängen doch von der Länge des Eingangsarrays ab.
... von der Länge des Eingangsarrays an der For-Schleife (die mit den vier Minus, nicht die erste!). Und diese Arrays kommen von den Schieberegistern. Und von denen glaube ich ja, dass die sich aufsummieren.
Zitat:Dieses ist eigentlich immer 30000 Zeilen lang, also 30000 durchläufe.
Mann, bin ich blöd: Ich kann's doch selben probieren.
Zitat:werden dann dabei die berüchtigten Array-Copy´s angelegt die im Speicher verweilen?
Ja.
Zitat:Das "in place structure" element kann man nicht um Vorschleifen bauen?
Nein, kann man nicht.
LV arbeitet ja nach dem Prinzip des Datenflusses. Das heißt aber, dass immer dann, wenn ein Wire entsteht oder verzweigt wird, eine Kopie der Daten angelegt wird. Das ist aber z.B. dann nicht notwendig, wenn man lediglich z.B. in einem Array einen Wert verrechnen und in den selben Index speichern will. Das Inplacement erzwingt also eine Pointer-Operation ohne Speicherallozierung anstelle eines Datenflusses mit Speicherallozierung. Inplacements sind Operationen mit einem einzigen Pointerwert. Bei Plazieren des Inplacements in die FOR-Schleife würde man ja ein Inkrementieren des Pointers haben wollen. Das geht aber (noch) nicht.
[*grübel*]
Implacement macht also nur dann Sinn, wenn eine Verrechnung stattfindet. Alleine ein Ersetzen bringt keine Vorzeile.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
' schrieb:Mit dem "Performance and Memory Profile" tool habe ich herausgefunden das dort mein Speicher voll läuft, nach ca. 200 Dateien (eine Datei ca 8 Mb) ist der Speicher voll und LV beendet die ausführung.
Halo STG,
da hast Du direkt das passende Tool zum detektieren.Wenn Du jetzt noch den Rat von IchSelbst folgst alles in Sub-Vi zu lösen kannst Du genau mit diesem Tool sehen welches "zukünftige" Sub-Vi verbessert werden muss.
' schrieb:Halo STG,
da hast Du direkt das passende Tool zum detektieren.Wenn Du jetzt noch den Rat von IchSelbst folgst alles in Sub-Vi zu lösen kannst Du genau mit diesem Tool sehen welches "zukünftige" Sub-Vi verbessert werden muss.
Gruß
Ralf
Hey Rasta Ralle :-)
Die idee ist mir heute beim Frühstück auch gekommen. Man is ja doch faul, und die 3 änderungen die ich heut nacht noch gemacht haben brachten nur leichte verbesserungen. WErd mal schauen wo der Fehler genau steckt und mich später nochmal melden.
Vielen Dank erstmal für eure Unterstützung!
MfG Richard
19.12.2009, 15:29 (Dieser Beitrag wurde zuletzt bearbeitet: 19.12.2009 15:32 von IchSelbst.)
Guckst du Sonden. Sonde Zwei zeigt die Länge des Arrays, das weiterverarbeitet wird. Diese Länge bleibt konstant. Sonde Eins zeigt die Länge eines jeden Schieberegisters. Diese Länge wächst pro SubVI-Aufruf um 30000 an (= die Länge der einen Dimension des Eingangsarrays, rate mal wie oft ich das SubVI hab laufen lassen). Das machst in Summe wohl ca. 4 bis 5 MB pro Aufruf (vergleiche Taskmanager von Windows). 200 Aufrufe => 1GB => Speicher voll. In diesem Falle nützt auch ein Inplacement nichts.
Das Array, dessen Länge Sonde Zwei anzeigt, ist deswegen nur 30000 lang und nicht 120000, weil das Element InArrayEinfügen von den 120000 Elementes des einzufügenden Arrays eben nur 30000 nimmt.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).