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!
ich habe ein grundlegendes Problem mit dem Speichern von Daten.
Ich habe ein Programm geschrieben, welches mehrere Multimeter steuert. Dazu werden zyklisch die Messdaten ausgelesen, dargestellt und gespeichert. Ich speichere einmal die Daten als Texfile und auch einmal als Binärdatei. Nach jeden Scan der Kanäle werden die anfallenden Daten aus einer Queue geholt und gespeichert (Datei öffnen, Schreiben, Datei schließen). Problem ist nur, dass das die CPU - Auslastung mit der wachsenden Dateigröße immer größer wird und irgendwann der Queue-Speicher vollläuft. Kann das sein das Dateien Schreiben schon ab 30Mb an seine Grenzen stößt oder mache ich da was falsch? Kann mir da jemand bitte weiterhelfen? Kann leider nichts aus dem Programm posten.
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
Problematik beim Schreiben von großen Messdateien
Ich kann mir gerade nicht vorstellen, was Du da machst. Wenn Du das Programm nicht hochladen kannst/darfst, kannst Du dann evtl. das Problem in einem kleinen Bsp. reproduzieren und dann hochladen?
Gruß Markus
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
Ich versuche große Datenmenge zu speichern. Liegen Daten an (2Hz a 50 Daten) sollen diese dynamisch zur Sicherung gespeichert werden. Ich habe festgestellt das die Speicherung in Abhängigkeit der Dateigröße mehr Zeit in Anspruch nimmt. Ich hoffe du kannst was mit dem Beispiel anfangen.
' schrieb:Ich versuche große Datenmenge zu speichern. Liegen Daten an (2Hz a 50 Daten) sollen diese dynamisch zur Sicherung gespeichert werden.
Große Datenmengen? 2Hz a 50 Daten? Fehlt vor Hz vielleicht ein k oder M? Alles andere sind nicht "große Datenmengen" !
Zitat:Ich habe festgestellt das die Speicherung in Abhängigkeit der Dateigröße mehr Zeit in Anspruch nimmt.
Wenn ich die obere For-Schleife sehe, kann ich dir zustimmen. Wie lange dauert es denn, bis die CPU-Zeit hochgelaufen ist?
Das Problem ist wie immer das Element "Array erzeugen". Das ist im Endeffekt ein Speicherfresser ohne Ende, was letztendlich auch den Prozessor belastet.
Folgendes:
Jedesmal - For-Schleife ! - wenn dieses Element ausgeführt wird, muss der Speichermanager neuen Speicherbedarf, der jedesmal etwas größer ist als zuvor, allozieren. Dann muss er das Array auch noch umkopieren. Bei dir treten noch weitere derartige "Probleme" auf. Dasselbe, nämlich die Sache mit dem Speichermanager, geschieht auch bei dem Ausgangstunnel an der For-Schleife. Und weiter geht's: Du schreibst die addierten Arrays per Referenz irgendwo hin: auch für jene Elemente muss neuer Speicher alloziert werden!
Eine Lösung für dieses Problem ist folgendes: Verwende nur Arrays, die in der Länge vorbesetzt sind (Array initialisieren mit fester Länge). Das "Array erstellen" wird dann ersetzt durch "in Array ersetzen". Dadurch entfallen alle Arbeiten mit dem Speichermanager. Die Elemente, die per Refnum angesprochen werden, kann man als FGV (funktionale globale Variable) machen, die dann selbst wieder in der Länge festgelegt sind.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
naja das mit der oberen for-Schleife habe ich aus einem Beispiel entnommen, wo mehere Kanäle in einem xy-Graph geplottet werden. Der Fehler mit der CPU, bzw. mit dem Speicherfehler tritt erst nach ca 10 Tagen Messung auf. Das mit der langen Umladezeit konnte ich einigermaßen kapieren, jedoch hat es mir nicht sehr weitergeholfen. Funktionale Globale Variablen hatte ich schon implementier, jodoch ohne Erfolg. Ich habe mal gehört das die While Schleifen im 1kHz Bereich arbeiten, wie soll man dann im Mhz Bereich Daten wegschaufeln können. Bin etwas verwirrt... Ich merke bei mir und LabVIEW gibt es ne Menge Potential nach oben:-)
' schrieb:Der Fehler mit der CPU, bzw. mit dem Speicherfehler tritt erst nach ca 10 Tagen Messung auf.
10 Tage zu 24 Stunden zu 3600 Sekunden macht bei 2 Hz und 50 DBL-Daten ca. 690MB. Naja.
Tastest du jetzt mit 2Hz ab oder mit mehr?
Zitat:Funktionale Globale Variablen hatte ich schon implementier, jodoch ohne Erfolg.
In wie weit ohne Erfolg? FGV und trotzdem Array-Addition bringt natürlich keinen Erfolg.
Zitat:Ich habe mal gehört das die While Schleifen im 1kHz Bereich arbeiten,
While-Schleifen arbeiten so schnell, wie man sie lässt. Ich lass sie immer mit 10Hz laufen - also alle 100ms. Ich sag mal ganz frech: Meine Prüfstände samplen 20 Daten mit 1kHz und die Prozessorzeit liegt alles in allem unter 5% - über Wochen.
Zitat:wie soll man dann im Mhz Bereich Daten wegschaufeln können.
In dem man entspechend große Datenpuffer verwendet.
Daten kommen für gewöhnlich vom DaqMX. Der hat aber einen Puffer, den man einstellen kann. Man muss ja nicht unbeding die Daten sample-weise abholen, anzeigen und speichern. Soll doch der DaqMX die Daten für (maximal) 200ms speichern, ich hol sie dann alle 100ms ab. Und dieses Vorgehen ist unabhängig von der Sample-Frequenz. Hinweis: Auch eine Queue hat Pufferwirkung.
Noch was zum Zeitbedarf:
Auch die Anzeige von Kurven an einem Graph kosten viel Zeit. Graphen sollte man also nur z.B. alle 250ms aktualisieren. Wenn der Graph noch ein Signalverlauf mit Historie ist, ist natürlich der Speicher für die Historienlänge zu beachten.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
ich habe nochmal ne Nacht drüber geschlafen und verstanden das die Problematik eindeutig bei dem Anzeigen der Daten liegt. Aber wie kann ich das jetzt genau machen. Ich weiß wie ich einen xy-Graph für einen Kanal programmieren kann, so dass das anstehenende Datum hinten rangehängt wird ohne die schon befindlichen Daten jedesmal zu kopieren. Aber wie geht das mit mehrenen Kanälen. Es wäre nett von dir wenn du mir das veranschaulichen könntest.
' schrieb:Aber wie kann ich das jetzt genau machen. Ich weiß wie ich einen xy-Graph für einen Kanal programmieren kann, so dass das anstehenende Datum hinten rangehängt wird ohne die schon befindlichen Daten jedesmal zu kopieren. Aber wie geht das mit mehrenen Kanälen.
Erstens:
Wenn du ein Signalverlaufsdiagramm verwendest, geht das mit dem Anhängen sowieso automatisch. Hier muss lediglich der neue Teil an den Eingang gelegt werden. Den Rest mach der Graph selbständig. Geht dann allerdings nur mit YT-Kurven, wenn dT konstant ist.
[*grübel*]
Automatisch auch bei XY-Graph? Hab ich noch nicht probiert. Naja, wenn du's sagst, glaub ich das.
Wenn was mit einem Kanal geht, muss das auch mit mehreren Kanälen gehen. Vorausgesetzt, der Graph ist für mehrere Kurven ausgelegt. Was ein Graph kann, respektive wie das Datenformat der Eingangsdaten aussieht, geht nur festzulegen, indem man das gewünschte Format an das Anzeigeelement anschließt (das Graph-Element ist polymorph!). Wenn man also mehrere XY-Kurven darstellen willst, musst man das Anzeigeelement mit diesem Typ beschalten. Verbinden mit lokaler Variable oder Property zur Formateinstellung funktioniert nicht.
Wie hast du das denn gemacht, dass der XY-Graph die neuen Daten selbständig hinten anhängt? Kannst du mal ein Muster-VI machen (Bild geht auch)?
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
17.10.2009, 08:33 (Dieser Beitrag wurde zuletzt bearbeitet: 18.10.2009 12:33 von jg.)
Erstens:
Da du die beiden Arrays X und Y1 mit einem leeren Array vorbesetzt hast, entspricht das Element "In Array ersetzen" einem "An Array anhängen" => Speichermanager!
Zweitens:
Lieber (wo es halt eben geht) vorbesetzt wie Y2. Dann ist ein "In Array ersetzen" auch ein echtes Replace. Mit NaN wird vorbesetzt, weil der Graph - intelligenterweise - alle die Punkte weglässt, die ein NaN beinhalten.
Drittens:
Das Element "Array erstellen" (nach dem Bundlen der zwei XY-Kurven) muss nicht zwangsweise zu einer Speichermanager-Operation führen. Der Compiler könnte (ist es wahrscheinlich auch) so intelligent sein, und hier zur Laufzeit optimieren, sodass kein Speicher alloziert werden muss.
Viertens:
So wie der Graph mit Daten beaufschlagt wird, ist das aber kein Anhängen an bestehende Daten in der Graph-Anzeige! So wie es ist, wird jedesmal ein kompletter Datensatz an den Graphen übergeben. Also von T0 = Anfang bis Tende. Und genau das kostet bei größen Arrays eben sehr viel Zeit im Graph-Element (im übrigen: wohl auch das Graph-Element bedient sich des Speichermanagers).
Probier hier mal ein Signalverlaufsdiagramm (oder Signalverlaufsgraph). Die machen nämlich genau das: Hier wird nur z.B. das Zufallszahlen-Element direkt (oder indirekt über ein 1DArr bei mehreren Kurven) an die Graph-Anzeige gehängt. Obwohl hier nur eine Zahl hängt (also kein Array oder Cluster) wird ein Graph, also die neue Zahl + die Historie, angezeigt. Zwar bedient sich gewiss auch ein Signalverlaufsdiagramm des Speichermanagers. Ich denke doch aber, dass LV hier Optimierungen vornimmt.
Fünftens:
Guckst du Hilfe von Graph. Da steht, mit welchem Datentyp das Anzeigeelement beschaltet werden kann. Entweder ein Cluster aus zwei Stück 1DArr oder eben ein Array aus Cluster aus 2 Stück 1DArr.
Noch ein Hinweis:
Das Azeigen von Daten über einen Zeitraum von 10 Tagen im Raster von einer Sekunde ist kritisch. Das gibt viel zu viel Daten im Graphen, die sowieso nicht angezeigt werden können - weil der Bildschirm viel zu schmal ist. Hier lieber in File auslagern, eine eigene Datenkomprimierung machen (ganz einfach im Falle eines Falles: nur jeden 1000ten anzeigen) und diese Daten dann anzeigen.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).