Effizienzsteigerung: Data Viewing & Logging in QSM
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!
19.10.2015, 15:10 (Dieser Beitrag wurde zuletzt bearbeitet: 19.10.2015 15:23 von ExXeQtor.)
Effizienzsteigerung: Data Viewing & Logging in QSM
Hallo,
ich habe über die letzten Monate zur Steuerung und DAQ einer selbstgebauten Hardware eine inzwischen ziemlich umfangreiche Queued State Machine (QSM) aufgebaut, bei der ich nun an einer Stelle an meine Grenzen komme. Zum Verständnis kurz:
*Ein Event Handler verarbeitet Eingaben vom Nutzer und sendet Prompts an die QSM
*Eine QSM - Communicator - (die eigentliche State machine), die zum Daten Holen (Treiber) und Processen gut ist
*Eine QSM - Data Consumer - die im Wesentlichen immer dann, wenn ein Datenpaket vom Communicator in die Queue gelegt wurde, dieses herausholt und
a) Zur Visualisierung in Charts steckt
b) in Textdateien loggt.
Mein problem nun ist, dass die Data Consumer QSM, obwohl sie nicht "viel" tut, immer ins Nachhängen kommt, was man an der Anzahl der wartenden Elemente in der zugehörigen Queue erkennt, die ab einer bestimten Datenmenge nur noch größer wird (also nicht mehr schnell genug abgearbeitet wird). Hierzu hoffe ich auf Tips von euch. Dazu im Anhang ein Bild der betreffenden QSM zum Nachvollziehen. das komplette VI darf ich nicht hochladen, nur die consumer qsm extrahieren geht nicht (weil mehr als 24 eingänge).
Zu den Fakten/ der Datenmenge:
Es gibt drei Typen von "Datenpaketen", die die Consumer-QSM erreichen.
- Der erste Typ kommt mit einer Samplerate von ca 500Hz und 6(channel)* 24Bit
- Der zweite Typ kommt mit einer Samplerate von 16Hz und 8(channel)* 24 Bit
- Der dritte Typ - Accelerometer im Bild - kommt mit 50Hz *4(channel)* 16Bit
Das bedeutet, es müssen pro Sekunde- neben den anderen Aufgaben des GUIs - ca. 10kByte an Daten visualisiert und geloggt werden.
Viele Channel werden durch einen eigenen Chart visualisiert, das heißt es gibt 16 Charts, mit jeweils History Lengths von 5000 Samples und zT deutlich weniger.
Das Data logging passiert in TXT dateien im ASCII CSV format für ein besseres Interface zu Software wie excel, matlab etc: Jeder Typ daten bekommt ein eigenes TXT - also wird in drei Daten geloggt.
Im Anhang kann man also sehen was passiert, wenn ein Datenpaket vom Typ "ACCEL" reinkommt: die 16Bit daten werden umgerechnet und dann direkt in die jeweiligen charts gesteckt sowie als CSV string an das log-file angehängt. So läuft es auch mit den anderen Datenpaketen.
DAS IST ZU LANGSAM!
Schalte ich das Data-Logging aus, bleibt die Anzahl der Queue-Elemente bei 1/0 - wird also immer schnell genug abgearbeitet. Wird in die files geloggt, steigt die anzahl der elemente pro sekunde um ca 10 - und das VI kommt nicht mehr hinterher.
Wie kann ich die Daten effizienter - aber bestenfalls im selben Format - loggen? Oder bleibt mir da nur binär, was die datenmenge enorm reduzieren würde, weil kein ASCII- was aber auch bedeuten würde, dass ich noch einen converter für später schreiben muss?
RE: Effizienzsteigerung: Data Viewing & Logging in QSM
Erster Edit Zweiter Schnellschuß:
File-Logging in eigener Schleife, und hier dafür sorgen, dass nicht jeder Datensatz einzeln geschrieben wird, sondern z.B. immer 1000 Datensätze auf einmal.
Deine grob 600 Filezugriffe pro Sekunde sind schon heftig.
Gruß, Jens
P.S.: Der PropertyNode kann ich mich nur anschließen.
Wer die erhabene Weisheit der Mathematik tadelt, nährt sich von Verwirrung. (Leonardo da Vinci)
!! BITTE !! stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort!
RE: Effizienzsteigerung: Data Viewing & Logging in QSM
Danke für beide Hinweise!
@Holger:
Mir war zwar dunkel bekannt, dass property nodes "böse" sind, aber warum (auch in diesem Fall) war/ist mir unklar (gewesen)!
@Jens:
Wie würdest du die daten zwischenpuffern? Gleich in einem String-Array?
Grüße
Alex
Edit:
Gibt es einen schnelleren Weg die property nodes direkt zu globalen variablen zu machen - ein replace o.ä.? Sonst steht da einiges an Arbeit bevor...
RE: Effizienzsteigerung: Data Viewing & Logging in QSM
(19.10.2015 15:28 )ExXeQtor schrieb: @Jens:
Wie würdest du die daten zwischenpuffern? Gleich in einem String-Array?
Da gibt es verschiedene Möglichkeiten. Was am Ende am besten und speicherschonendsten ist, das musst du ausprobieren.
Mgl. Ideen:
- Einen Ringbuffer (FGV) anlegen, der immer wieder weggeschrieben wird.
- Die Werte per weiterer Queue an einen anderen Prozess weitergeben. Ob du hierbei die Numeric-Arrays oder die Strings weitergibst und was mglw. schneller ist -> Ausprobieren. Im Speicherprozess dann nicht jedes Queue-Element einzeln auswerten, sondern z.B. jede Sekunde alle anstehenden Elemente auf einen Rutsch auslesen, Zusammenfassen und dann die Zusammenfassung nur 1x pro Erfassungstyp wegspeichern.
(19.10.2015 15:28 )ExXeQtor schrieb: Edit:
Gibt es einen schnelleren Weg die property nodes direkt zu globalen variablen zu machen - ein replace o.ä.? Sonst steht da einiges an Arbeit bevor...
Du könntest dich mit LabVIEW Scripting beschäftigen, ist aber nicht ohne...
Gruß, Jens
Wer die erhabene Weisheit der Mathematik tadelt, nährt sich von Verwirrung. (Leonardo da Vinci)
!! BITTE !! stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort!
RE: Effizienzsteigerung: Data Viewing & Logging in QSM
(19.10.2015 15:10 )ExXeQtor schrieb: *Ein Event Handler verarbeitet Eingaben vom Nutzer und sendet Prompts an die QSM
*Eine QSM - Communicator - (die eigentliche State machine), die zum Daten Holen (Treiber) und Processen gut ist
*Eine QSM - Data Consumer - die im Wesentlichen immer dann, wenn ein Datenpaket vom Communicator in die Queue gelegt wurde, dieses herausholt und
a) Zur Visualisierung in Charts steckt
b) in Textdateien loggt.
So mach ich das auch. Nur: Die Sache mit den Queues mach ich noch viel mehr ...
Mach dir viele QSM (bei mir heißen diese VIs Klassen und sind FGVs), wo jede eine genau definiert Aufgabe hat. z.B. eine FGV für Loggen. Diese FGV, weil ja eine Klasse, hat ein Property, das Loggen heißt. Mit dem Aufruf dieses Property (über einen Enumerator ...) wird Klassen-intern(!) das Flag "Loggen" manipuliert. Diese Vorgehensweise hat den Vorteil, dass ein Algorithmus (Daten loggen) von der Bedieneroberfläche getrennt wird (Property-Node). Nächster Vorteil: Ein VI wird schön klein und übersichtlich. Alles das, was du jetzt als Algorithmus "Loggen" (File schreiben etc.) siehst, wird dann als ein einziger VI-Aufruf (Daten per Queue an Modul senden), erscheinen.
Ebendieses gilt natürlich auch für die Anzeige im Graph. QSM (als FGV mit private-variablen) machen, Daten und Steuerwerte per Queue senden: Wenn der Anwender (oder wer auch immer) ctrl_accel_range ändert, wird genau in dem Moment, in dem geändert wird, einmalig der Steuerwert ctrl_accel_range in die QSM geschickt - und dort als ganz normale private Variable (z.B. in einem Schieberegister) verwaltet ...
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
20.10.2015, 14:36 (Dieser Beitrag wurde zuletzt bearbeitet: 20.10.2015 15:10 von ExXeQtor.)
RE: Effizienzsteigerung: Data Viewing & Logging in QSM
Danke für eure Antworten!
Ich habe das ganze jetzt mit globalen variablen und 1/1000 so häufigem Schreibzugriff (über concatenated strings) gelöst - und es läuft!
Dabei ist allerdings eins merkwürdig: Nach ca. 30sek werden die charts nur noch ca. alle 500ms geupdated - obwohl die queue "leer" bleibt und die history length ja von vorneherein begrenzt ist (und schon oft neu gefüllt wurde bis zu diesem zeitpunkt). Die daten werden also schnell genug verarbeitet und geloggt - trotzdem ein ruckeliges "refreshing" der charts.
Kann das nun daran liegen, dass labview die offenen (und immer größer werdenden) txt-dateien ersteinmal nach dem Ende suchen muss um dort anzuhängen? ich war irgendwie davon ausgegangen, dass diese info im refnum steckt...
EDIT: Ja nee... wenn ich das logging ausgeschaltet habe, passiert das selbe.
EDIT2: Ok, bitte ignorieren: Das lag an etwas ganz anderem, einem string zur datenanzeige, den ich immer weiter angehängt habe (aber nie mal gekürzt).