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!
10.08.2009, 11:20 (Dieser Beitrag wurde zuletzt bearbeitet: 10.08.2009 19:15 von jg.)
EDIT Jens G:
Innerhalb des Beitrages: http://www.LabVIEWforum.de/index.php?showtopic=13731
hatte sich eine zweite Diskussion um 1D-/2D- und 3D-Arrays entwickelt. Nachdem das im Originalthread etwas verwirrend wurde, habe ich die entsprechenden Beiträge hierher verschoben.
Hier also:
' schrieb:Mir fällt jetzt spontan kein Grund ein, warum ich auf Array mit mehr als 2 Dimensionen verzichten sollte. Darf ich deshalb fragen, wieso du sie vermeidest?
Ich habe schon Probleme mehr als 250 Bilder mit einer Kamera der Auflösung 320x256 Pixel mit 3D-Arrays aufzunehmen (Speicherüberlauf). LV handled alles was über 1 Dimension hinaus geht einfach "schlecht". Im Prinzip weiß kaum jemand das er damit Speicher allokiert. LV macht es einem also leicht Speicher zu reserviren, aber lässt einem diesen nicht wieder einfach so freigeben. Ich arbeite also immer mit 1D Arrays in LV.
10.08.2009, 11:43 (Dieser Beitrag wurde zuletzt bearbeitet: 10.08.2009 11:45 von unicorn.)
' schrieb:Ich habe schon Probleme mehr als 250 Bilder mit einer Kamera der Auflösung 320x256 Pixel mit 3D-Arrays aufzunehmen (Speicherüberlauf). LV handled alles was über 1 Dimension hinaus geht einfach "schlecht". Im Prinzip weiß kaum jemand das er damit Speicher allokiert. LV macht es einem also leicht Speicher zu reserviren, aber lässt einem diesen nicht wieder einfach so freigeben. Ich arbeite also immer mit 1D Arrays in LV.
Vor allen Dingen wird der Speicher als hintereinanderliegender Speicher gebraucht, so dass auch schon mal "recht kleine" Felder nicht angelegt werden können. Wird das Array an ein SubVI überreicht, so wird der Speicher noch mal gebraucht um die Daten zu kopieren. Hierzu gibt es bei NI geeignete Dokumente die das beschreiben. Um längere Arrays im Speicher haben zu können (z. B. 600 Bilder mit 658 X 496 Bildpunkten) bedarf es ein paar Tricks. Ich habe dazu kein 3D Array angelegt sondern ein Array (mit 600 Frames) von einem Cluster mit einem 2D-Array (von 658 x 496 Bildpunkten). Jetzt legt LV die Bilddaten nicht mehr hintereinander weg in den Speicher, sondern reserviert für jedes einzelne Bild einen eigenen Block, die irgendwo im Speicher sein können. Zusätzlich ist das ganze Array in einer While-Schleife mit Shift-Register untergebracht und ich greife per Index nur noch auf einzelne Bilder zurück.
Beim Rücksprung aus einem SubVI kann man von LV eine Speicherfreigabe anfordern: Application control > Memory Control > Request Deallocation.vi
10.08.2009, 11:44 (Dieser Beitrag wurde zuletzt bearbeitet: 10.08.2009 11:49 von schrotti.)
' schrieb:Ich habe schon Probleme mehr als 250 Bilder mit einer Kamera der Auflösung 320x256 Pixel mit 3D-Arrays aufzunehmen (Speicherüberlauf). LV handled alles was über 1 Dimension hinaus geht einfach "schlecht". Im Prinzip weiß kaum jemand das er damit Speicher allokiert. LV macht es einem also leicht Speicher zu reserviren, aber lässt einem diesen nicht wieder einfach so freigeben. Ich arbeite also immer mit 1D Arrays in LV.
Mit 32 Bit pro Pixel wären es knapp 80 MB. Da dürfte es selbst mit der übelsten Speicherverwaltung keine Probleme geben. Nur mit 1D-Array zu arbeiten ist in LV gar nicht möglich und in manchen Fällen sind durch den Verzicht auf 2D-Array mehr Ressourcen notwendig als mit. Wenn ich beispielsweise 8 Kanäle auf die HD streamen will läuft das auf jeden Fall mit einem 2D-Array schneller als mit 8 1D-Arrays und 8 Aufrufen der Speicherfunktion. Dass LV den Speicher nicht gerade auf die eleganteste Art und Weise handelt ist mir bekannt. So sollte ja auch auf Cluster mit Array mit Clustern... verzichtet werden. Dass aber LV so schlecht ist wie du sagst, kann ich mir nicht so recht vorstellen. Meiner Erfahrung ist die, dass LV in der Lage ist, große Array einigermaßen zu handeln, viele Nutzer aber ständig Kopien anlegen und dadurch den Speicher zumüllen.
' schrieb:Vor allen Dingen wird der Speicher als hintereinanderliegender Speicher gebraucht, so dass auch schon mal "recht kleine" Felder nicht angelegt werden können. Wird das Array an ein SubVI überreicht, so wird der Speicher noch mal gebraucht um die Daten zu kopieren. Hierzu gibt es bei NI geeignete Dokumente die das beschreiben. Um längere Arrays im Speicher haben zu können (z. B. 600 Bilder mit 658 X 496 Bildpunkten) bedarf es ein paar Tricks. Ich habe dazu kein 3D Array angelegt sondern ein Array (mit 600 Frames) von einem Cluster mit einem 2D-Array (von 658 x 496 Bildpunkten). Jetzt legt LV die Bilddaten nicht mehr hintereinander weg in den Speicher, sondern reserviert für jedes einzelne Bild einen eigenen Block, die irgendwo im Speicher sein können. Zusätzlich ist das ganze Array in einer While-Schleife mit Shift-Register untergebracht und ich greife per Index nur noch auf einzelne Bilder zurück.
Beim Rücksprung aus einem SubVI kann man von LV eine Speicherfreigabe anfordern: Application control > Memory Control > Request Deallocation.vi
Der Block kann aber nicht irgendwo im Speicher sein. LV kann nur einen zusammenhängenden Speicherbreich verwalten. Die Bilder liegen können also nur igendwo da drinnen rumliegen.
Die Speicherfreigabe ist aber mehr eine Bitte als Befehl. LV muss das nicht machen.
' schrieb:Beim Rücksprung aus einem SubVI kann man von LV eine Speicherfreigabe anfordern: Application control > Memory Control > Request Deallocation.vi
Bei mir hat er auch damit nie den Speicher freigegeben. Das ist nur eine höfliche Bitte an LV Speicher frei zu geben. Ob es das macht ist eine andere Sache.
' schrieb:Mit 32 Bit pro Pixel wären es knapp 80 MB. Da dürfte es selbst mit der übelsten Speicherverwaltung keine Probleme geben.
Probier es doch einfach mal. Ich kann dir nur sagen das es bei mehr als 250 Bilder (nur 16Bit pro Pixel) zu besagtem Überlauf kommt.
' schrieb:Nur mit 1D-Array zu arbeiten ist in LV gar nicht möglich und in manchen Fällen sind durch den Verzicht auf 2D-Array mehr Ressourcen notwendig als mit. Wenn ich beispielsweise 8 Kanäle auf die HD streamen will läuft das auf jeden Fall mit einem 2D-Array schneller als mit 8 1D-Arrays und 8 Aufrufen der Speicherfunktion.
Sicher ist es möglich. Sag mir mal was ich in einem 1D array nicht eblegen kann was ich in einem 2 oder 3D Array ablegen kann? Ich würde nicht 8 1D-Arrays sondern ein 1D-Array mit genügent Elementen alnegen.
' schrieb:Dass LV den Speicher nicht gerade auf die eleganteste Art und Weise handelt ist mir bekannt. So sollte ja auch auf Cluster mit Array mit Clustern verzichtet werden. Dass aber LV so schlecht ist wie du sagst, kann ich mir nicht so recht vorstellen. Meiner Erfahrung ist die, dass LV in der Lage ist, große Array einigermaßen zu handeln, viele Nutzer aber ständig Kopien anlegen und dadurch den Speicher zumüllen.
Den Nutzer lass ich einfach mal aus dem Spiel, da er nichts dafür kann. Er möchte nur eine Software die macht was sie soll. Ich habe bisher nur schlechte Erfahrungen mit den LV-Eigenen Methoden mit großen Datenmengen umzugehen gemacht.
' schrieb:Probier es doch einfach mal. Ich kann dir nur sagen das es bei mehr als 250 Bilder (nur 16Bit pro Pixel) zu besagtem Überlauf kommt.
Habs gerade mit 32 Bit ausprobiert und kein Problem erkennen können.
' schrieb:Sicher ist es möglich. Sag mir mal was ich in einem 1D array nicht eblegen kann was ich in einem 2 oder 3D Array ablegen kann? Ich würde nicht 8 1D-Arrays sondern ein 1D-Array mit genügent Elementen alnegen.
Die Konsequenz wäre nur ein Kanal in der Datei, den ich später aufwendig aufdrösseln muss. Natürlich kann ich das machen, aber Vorteile habe ich damit nicht.
' schrieb:Den Nutzer lass ich einfach mal aus dem Spiel, da er nichts dafür kann.
Ich meinte damit den Nutzer der LabVIEW Entwicklungsumgebung.
' schrieb:Der Block kann aber nicht irgendwo im Speicher sein. LV kann nur einen zusammenhängenden Speicherbreich verwalten. Die Bilder liegen können also nur igendwo da drinnen rumliegen.
Die Speicherfreigabe ist aber mehr eine Bitte als Befehl. LV muss das nicht machen.
Nun auf meinem Rechner macht es einen Unterschied, ob ich ein Array aus einem Cluster mit einem 2D-Array anlegen, oder ob ich ein 3D-Array mit den genannten Dimensionen anlege. Es klappt nur ersteres. Der Rechner hat 1 GB Hauptspeicher und nutzt im ersten Fall natürlich die Auslagerungsdatei intensiv. Im zweiten Fall bricht er bei etwa 70 Bildern mangels Speicher ab. Nach Deiner Aussage müsste ja beides gehen.
Irgendwo habe ich gelesen, dass LV Speicher nur am Stück allokieren kann. Wie LV darin den Speicher verwaltet weiß ich glaube dir, dass die von dir genannte Methode besser klappt. Eigentlich auch logische, denn die Array innerhalb der Clusterelemente können unterschiedlich groß sein. LV kann somit keinen aneinanderhängenden Speicher belegen sondern setzt nur einen Pointer auf das Array rein. Wie LV dann vorgeht, um dieses Array zu speichern, weiß ich nicht. Es kann allerdings nicht irgendwo im Speicher liegen, da LV wie gesagt nur einen Bereich verwalten kann.
' schrieb:Sicher ist es möglich. Sag mir mal was ich in einem 1D array nicht eblegen kann was ich in einem 2 oder 3D Array ablegen kann? Ich würde nicht 8 1D-Arrays sondern ein 1D-Array mit genügent Elementen alnegen.
Hmm, ein 2D Array mit 8 Kanalen a 1MS verbraucht genau 8 * 10^6 * 8 + 8 Bytes und noch etwa 16 Byte LabVIEW Handle overhead (~64'000'024 Bytes). Ein 1D Array das dieselben Daten enthalten kann würde 8 * 10^6 * 8 + 4 Bytes und den LabVIEW handle overhead belegen (~64'000'020 Bytes). Beides ist ein kontinuierlicher Bereich im Speicher. Es erscheint mir sehr unwahrscheinlich dass die 4 Bytes Unterschied einen merkbaren Unterschied darstellen!
Das Problem ist nicht 2D, 3D oder nD Arrays sondern der einfache Fakt dass mit solchen Arrays sehr schnell sehr viel Speicher alloziert werden muss ohne dass der Benützer das direkt sieht. Aber der Trick um alles in ein 1D Array zu stopfen bringt nichts wenn man die gleichen Daten darin haben will. Der einzige Vorteil liegt darin, das man dazu erst wirklich gut nachdenken muss und schnell sieht dass das enorme Daten ergibt und dadurch vielleicht gezwungen wird das ganze Design zu überdenken.
' schrieb:Irgendwo habe ich gelesen, dass LV Speicher nur am Stück allokieren kann. Wie LV darin den Speicher verwaltet weiß ich glaube dir, dass die von dir genannte Methode besser klappt. Eigentlich auch logische, denn die Array innerhalb der Clusterelemente können unterschiedlich groß sein. LV kann somit keinen aneinanderhängenden Speicher belegen sondern setzt nur einen Pointer auf das Array rein. Wie LV dann vorgeht, um dieses Array zu speichern, weiß ich nicht. Es kann allerdings nicht irgendwo im Speicher liegen, da LV wie gesagt nur einen Bereich verwalten kann.
Das war Windows 3.1.
Seit Windows wirklich 32 Bit ist bekommt eine Applikation grundsätzlich einen 2GB (3GB mit speziellem boot.ini Eintrag, aber es ist keine gute Idee diesen Switch grundsätzlich zu verwenden, da er denn Speicher für den Kernel auf 1GB begrenzt und damit den Kernel ziemlich stark einschränkt) virtuellen Adressbereich zugewiesen.
Ob der auch alloziert werden kann hängt natürlich vom wirklich vorhandenen Speicher ab. LabVIEW fragt jeden Speicher ganz einfach beim OS an, und ja ein einzelnes Array muss ganz in einem einzigen aneinanderliegenden Block abgespeichert werden. Windows wählt irgendeinen Block im Speicherraum der gross genug ist und gibt diesen zurück. Die virtuelle Speicherverwaltung von x86 Prozessoren hat aber ihre Beschränkungen und kann nicht beliebig viele einzelne Speicherblöcke im virtuellen Speicherraum verwalten, da jeder Block auch wieder entsprechende Verwaltungsresourcen erfordert. Irgenwann mal gibt es entweder nicht mehr genug Speicherdeskriptoren für solche Blöcke oder aber der Speicher wurde inzwischen so fragmentiert dass Windows nicht mehr einfach einen genügendgrossen aneinanderhängenden Speicherblock allozieren kann. Beides resultiert in einem Out of Memory error.
LabVIEW könnte versuchen einen eigenen Memory Manger zu verwenden so wie es das in Windows 3.1 tat und wäre damit vielleicht im Stande in gewissen Grenzfällen eine bessere Verwendung der 2GB zu machen aber das käme mit extra Kosten da es auch wieder Speicher benötigte um die Speicherblöcke selber zu verwalten, was sowohl vom Speicher abginge als extra Laufzeit fragen würde. Windows kann das mindestens so schnell resp. dank der direkten Verwendung der x86 MMU Hardware sogar schneller aber ist nicht unbedingt optimalisiert für Applikationen die eventuel riesige kontinuierliche Speicherblöcke anlegen möchten.