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!
07.12.2008, 11:29 (Dieser Beitrag wurde zuletzt bearbeitet: 07.12.2008 14:19 von Lucki.)
' schrieb:Zitat: "Bis Du hier nicht ein wenig zu streng?" - Nein
Aber es ist mir beim Post an den falschen Adressaten gerutscht, du hattest ja geschrieben das noch kleine Fehler enthalten sein können.Sorry
Mit Speicherleck meine ich wenn die Applikation tagelang läuft und hunderte Dateien geöffnet (Referenz) und nicht wieder geschlossen (freigegeben) werden, dass dann halt der Speicher leckt.
Diese Effekt kenne ich sehr wohl, aber ich hatte immer geglaubt, daß LabVIEW solche geöffneten Dateien - im Unterschied beispielsweise zu dem uralten Turbo-Pascal - auf jeden Fall von sich aus schließt, wenn das Programm beendet wird. Aber du wirst recht haben, und statt das umständlich zu erforschen werde ich mich lieber gleich bessern.
Gruß Ludwig
Da es weniger sinnvoll ist, eine Datei zu halbieren (dabei geht nämlich möglicherweise ein Datensatz verloren; einer ist 17, einer 18 Zeichen lang), hab ich mal was vorbereitet, um in verschiedenen Cores jeweils eine ganze Datei zu decodieren. Die Daten (Vorgabedaten und decodierte Daten) werden zwischen dem Decodier-SubVI, das in mehreren Instanzen geöffnet werden kann, und dem MainVI per Queue übertragen.
Den Instanzen muss nur noch ein Core zugewiesen werden. Da weiß ich aber nicht Bescheid.
Kann mal einer probieren, ob das funktioniert?
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
' schrieb:Da es weniger sinnvoll ist, eine Datei zu halbieren (dabei geht nämlich möglicherweise ein Datensatz verloren; einer ist 17, einer 18 Zeichen lang), hab ich
Ja da haste wohl recht, alternativ kann man die Datei ganz einlesen und die verschiedenen Case´s parallel abarbeiten.
' schrieb:Den Instanzen muss nur noch ein Core zugewiesen werden. Da weiß ich aber nicht Bescheid.
In deinem Beispiel hast du ja schon Multicore-Unterstützung (Anzahl der Reentrant Sub-Vi´s). Du könntest die Anzahl der Core´s über eine
Case-Auswahl treffen mit der entsprechenden Anzahl der Sub-Vi´s.
Eine direkte Core-Auswahl ist mit der Timed-Loop möglich.
Hier ist mal ein (hoffentlich) interessanter Link: http://zone.ni.com/devzone/cda/tut/p/id/6616
' schrieb:Da es weniger sinnvoll ist, eine Datei zu halbieren (dabei geht nämlich möglicherweise ein Datensatz verloren; einer ist 17, einer 18 Zeichen lang), hab ich mal was vorbereitet, um in verschiedenen Cores jeweils eine ganze Datei zu decodieren. Die Daten (Vorgabedaten und decodierte Daten) werden zwischen dem Decodier-SubVI, das in mehreren Instanzen geöffnet werden kann, und dem MainVI per Queue übertragen.
Den Instanzen muss nur noch ein Core zugewiesen werden. Da weiß ich aber nicht Bescheid.
Kann mal einer probieren, ob das funktioniert?
Das war von mir ein Irrtum: Beide Datensätze sind 18*(2Byte) lang. Die Anzahl der Integer ist unterschiedlich, aber der eine Datensatz enthält U16 + U16, der andere U8 + U8 + U16, so daß die Gesamtlänge in beiden gleich ist.
Deine Datei sehe ich mir noch an, obwohl ich leider nur einen Core habe.
Bei dem edlen Wettstreit um höher, weiter, schneller kann ich doch nicht abseits stehen, und habe noch mal alles Speicherplatzmäßig und Geschwindigkeitsmäßig optimiert (für 1 Core)
Ergebnis:
Einlesen und Ausfiltern der Datensätze (= Sub-Vi, damit man den Speicher freigeben kann): 1.4sec
Sortier-SubVi: 0.4 sec
MainVI ohne Subvi-Zeiten: 1 sec
Macht in der Summe 2.8 sec
Speicherbedarf alles zusammen:
Die Tests wurden mit LV8.6 gemacht, abgespeichert ist aber
Gruß Ludwig
' schrieb:Da es weniger sinnvoll ist, eine Datei zu halbieren (dabei geht nämlich möglicherweise ein Datensatz verloren; einer ist 17, einer 18 Zeichen lang), hab ich mal was vorbereitet, um in verschiedenen Cores jeweils eine ganze Datei zu decodieren. Die Daten (Vorgabedaten und decodierte Daten) werden zwischen dem Decodier-SubVI, das in mehreren Instanzen geöffnet werden kann, und dem MainVI per Queue übertragen.
Den Instanzen muss nur noch ein Core zugewiesen werden. Da weiß ich aber nicht Bescheid.
Kann mal einer probieren, ob das funktioniert?
Du hast recht, die Datei halbieren geht wegen der möglichen Zerstörung eines Datensatzes nicht. Das ist ein Killler-Argument, wieso ist mir das nicht auch sofort aufgefallen?
Habe mir die VIs angesehen, und muß zugeben, davon verstehe ich überhaupt nichts. Das liegt aber nicht an Dir, sondern daran, daß ich zu den höheren Ebenen des Software-Engineering überhaupt keinen Zugang habe, bin da nur ein kleiner Elektroniker, der mit seinem gesunden Menschenverstand so gut es eben geht drauf los programmiert.
Für das von mir erstellte VI "GMS_ReadFile_Wa.vi" dauert das Einlesen der Daten 200ms und das anschließened Sortieren der Datensätze 1200ms. Also insgesamt 1400ms. (mit LV8.6). Bei Aufteilung auf mehrere Kerne ginge es also nur noch um Bruchteile einer Sekunde. Die Frage ob sich das evtl lohnt, kann nur Eugen beantworten. Wenn Eugen sich erst mal dazu aufraffen könnte, sein VI mit LV8.6 statt mit LV8.0 laufen zu lassen, wäre die Verbesserung wahrscheinlich viel gravierender.
Ich sehe, dass das Thema hier superheiss diskutiert wird. Das Programm ist schon längst beim Kunden. Ich werde keine Änderungen mehr einprogrammieren. Mit 2-3 Sekunden Wartezeit ist der Kunde und ich auch einverstanden. Klar wäre es besser, wenn man gar nicht warten würde, aber die paar Millisekunden machen mir gar nichts aus.
Alle Lösungen sind interessant. Insbesondere als sich die Ausführungszeit von 10 oder gar 18 auf 2 Sekunden reduziert hat. Das hat die Umstellung (vom Lucki vorgeschlagen) von Unflatten From String nach Arbeiten mit Arrays und Counters gebracht.
Der Vorschlag mit der Aufteilung auf zwei Cores hat nicht zu viel gebracht ist aber sicherlich für meine zukünftige Projekte interessant.
Ich habe jetzt das VI vom letzten Post ausprobiert und habe folgende Ergebnisse:
' schrieb:Das hat die Umstellung (vom Lucki vorgeschlagen) von Unflatten From String nach Arbeiten mit Arrays und Counters gebracht.
Ja, so ist es eben manchmal: Durch das Studium Deiner früheren Beiträge hatte ich die Funktion Unflatten from String für mich entdeckt. Und als es bei Dir jetzt um die Wurst ging, konnte der Schüler dem Lehrer zeigen, wie es damit lang läuft..
PS: Hast doch hoffentlich den fatalen Fehler korrigiert: Beide Datensatztypen sind 18 Doppelbytes lang, und nicht einer 17 und der andere 18.
08.12.2008, 12:16 (Dieser Beitrag wurde zuletzt bearbeitet: 08.12.2008 12:25 von eg.)
' schrieb:Ja, so ist es eben manchmal: Durch das Studium Deiner früheren Beiträge hatte ich die Funktion Unflatten from String für mich entdeckt. Und als es bei Dir jetzt um die Wurst ging, konnte der Schüler dem Lehrer zeigen, wie es damit lang läuft..
PS: Hast doch hoffentlich den fatalen Fehler korrigiert: Beide Datensatztypen sind 18 Doppelbytes lang, und nicht einer 17 und der andere 18.
Ich werde bestimmt weiterhin das Unflatten From String beim Parsen von einer Schnittstelle nutzen, da es wirklich einfach anzuwenden ist. Aber wenn es um solche Aufgaben wie jetzt geht, also wenn die Ausführungszeit wirklich eine große Rolle spielt, werde ich Arrays und Type Cast nehmen.
Das Unflatten From String hat noch einen klaren Vorteil - es kann Byte Order selbst handeln. Wir nutzen beim Kommunizieren ausschliesslich Little Endian Byte Order, ich hatte es mal mit Type Cast implementiert und es war nicht einfach (komplexes VI mit rekursiven Aufruf). Wahrscheinlich ist es im Unflatten genauso implementiert, plus Errorhandling - das macht bestimmt viel aus, was die Ausführungszeit angeht.