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!
1) UI-Thread (Eventstruktur - Timeout pollt Fehlerspeicher mit 4 Hz)
2) Ablaufsteuerung (Zustandsautomat, wird über Melder gesteuert)
3) SPS-Thread (Polling)
4) CAN-Thread (Polling und anschließend ggf bissle bidirektionale Kommunikation)
5) DAQ AI, 6) DAQ DO, 7)+8) DAQ CI 9) DAQ AO
Alles parallele Schleifen im MainVI, außer die ganzen DAQ Tasks, die starte ich über VI-Server (aber das macht ja keinen Unterschied). Läuft sehr gut. Auch im Vollbetrieb (alles quatscht und misst und schreibt plus Darstellung) - CPU-Last unter 20%. Prima.
Bei der anderen Maschine ist alles identisch (Programm und Hardware komplett gleich - Ok, Programm ist eine leichte Variation) nur ein popeliger Counter Task mehr und schon streiken einige Stellen. Z.B. beim lesen der CAN-Botschaften bekomme ich von der Funktion kein "rcv Queue emty" (weil zu langsam gelesen wird) und die Schleife liest sich ein Wolf. Schmeiße ich testweise irgendeinen DAQ Task raus (egal welchen) rennt wieder alles in gewohnt stoischer Gelassenheit.
Kann es denn echt sein, dass 9 Tasks locker bewältigt werden aber der 10. dann plötzlich das ganze Kartenhaus zum einstürzen bringt? Ich kann mich an Posts von "IchSelbst" erinnern wo er meint er lässt locker 20-30 Threads laufen.
PC issn Siemens Industrie Rechner (DualCore), Windows XP. (Guck morgen mal genauer falls relevant, weiß jetzt nicht mehr auswendig an Hardware).
Kommentar?
Gruß
„Sag nicht alles, was du weißt, aber wisse immer, was du sagst.“ (Matthias Claudius)
(28.09.2011 20:58 )dimitri84 schrieb: Ich kann mich an Posts von "IchSelbst" erinnern wo er meint er lässt locker 20-30 Threads laufen.
Ich auch.
Zitat:1) UI-Thread (Eventstruktur - Timeout pollt Fehlerspeicher mit 4 Hz)
2) Ablaufsteuerung (Zustandsautomat, wird über Melder gesteuert)
3) SPS-Thread (Polling)
4) CAN-Thread (Polling und anschließend ggf bissle bidirektionale Kommunikation)
5) DAQ AI, 6) DAQ DO, 7)+8) DAQ CI 9) DAQ AO
Sehe ich kein Problem - auch nicht mit zwei CI's.
Ich habe meine CI-Tasks aber nie als eigenen Thread laufen. Die (beiden) CI's-Tasks (leider muss man pro CI immer eine Task machen) laufen immer im Thread, der die AI-Task bedient. Und zwar deswegen, weil die CI-Samlpe-Daten parallel zu den AI-Sample-Daten laufen sollen. Die AI-Klasse liefert dann praktisch ein 2DArr, in dem die Daten von AI und CI stehen.
Eine dumme Bemerkung:
Unter 20 kann auch über 19 heißen. 19% aber ist viel. Anständig ist unter 5% - auch bei vielen Tasks und Threads (dauernde graphische Refreshes lass ich jetzt mal außen vor).
[*grübel*]
CAN müsste ich erst nochmal kucken. Ich weis gerade nicht, ob der einen eigenen Puffer hat. Versuch mal den CAN-Thread auch hohe Priorität zu setzen.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
29.09.2011, 14:26 (Dieser Beitrag wurde zuletzt bearbeitet: 29.09.2011 14:32 von dimitri84.)
(29.09.2011 13:54 )IchSelbst schrieb: Ich habe meine CI-Tasks aber nie als eigenen Thread laufen. Die (beiden) CI's-Tasks (leider muss man pro CI immer eine Task machen) laufen immer im Thread, der die AI-Task bedient.
Hmmm, passt bei mir nicht so gut. Ich brauche unterschiedlich große Datenblöcke (AI 50er, CI_1 1000er) -> Schleifezeit ist also unterschiedlich.
Zitat:Und zwar deswegen, weil die CI-Samlpe-Daten parallel zu den AI-Sample-Daten laufen sollen. Die AI-Klasse liefert dann praktisch ein 2DArr, in dem die Daten von AI und CI stehen.
Dazu müssen sie ja nicht in einem Thread laufen. Ich habe die SampleClock von dem AI Task als "externe" Taktquelle für den CI_2 Task geroutet (Wegencoder). (Wieso eigentlich 2DArr? Ich finde waveforms viel praktischer, vor allem für TDMS-Schreiben. Ich bau mir grundsätzlich aus den Countersignalen auch wavefroms auf Teufel komm raus ...)
Zitat:Eine dumme Bemerkung:
Unter 20 kann auch über 19 heißen. 19% aber ist viel. Anständig ist unter 5% - auch bei vielen Tasks und Threads (dauernde graphische Refreshes lass ich jetzt mal außen vor).
Ist schon so um die 10% rum ... Ich unterhalte gerne den Werker/Entwickler mit einem schönen bunten Graphen (ca. 15 Siganle - 5000 Samples Ringpuffer - xy Graph). Hab noch nie ausprobiert wie ohne Dartsellung ist.
Zitat:CAN müsste ich erst nochmal kucken. Ich weis gerade nicht, ob der einen eigenen Puffer hat. Versuch mal den CAN-Thread auch hohe Priorität zu setzen.
Also die CAN Karte hat einen Eingangpuffer ... ca 32k Nachrichten. Mit der Prioritätensetzung meinst du die VI-Eigenschaft? (Gibt ja auch bei der timed Loop sone Option.) Hab ich schon gemacht: auf "höchste Priorität". Dann habe ich tatsächlich wieder die "rcv Queue empty" Meldung bekommen und es ging wieder. Gefallen hat's mir aber nicht ...
Der Chef lässt noch einen Frequenzwandler springen (aus anderen Gründen) - damit spar ich mir den extra Counter wieder und habe so die identische Anzahl an Tasks auf beiden Maschinen. Alles rennt wieder. Aber was mich eben wundert, dass ein beliebieger Thread mehr/weniger schon soviel ausmacht. Kann ich fast nicht glauben. Nachher spiel ich mal ein bisschen mit der Prio-Vergabe im Taskmanager.
„Sag nicht alles, was du weißt, aber wisse immer, was du sagst.“ (Matthias Claudius)
habe ein ähnliches Problem. Und zwar lasse ich auch mehrere Schleifen parallel laufen.
1. DAQmx lesen (Wunsch 50Hz)
2. DAQmx schreiben (50Hz bis 10Hz möglich)
3. Hauptschleife, die Werte über Melder an "DAQmx schreiben" schickt und Programm und alle Schleifen via Melder beenden kann der nachträglich dann geschlossen wird
4. Automatikfunktion die im hintergrund alle 100ms schlummert und über eine Art Zustandsautomat über die Hauptschleife aufrufbar ist
5. Anzeigemöglichkeit für den Anwender, die alle 500ms läuft.
Nun habe ich die verschiedensten Versionen ausprobiert, aber meine ersten beiden Schleifen machen mir das Leben extrem schwer und spucken mir eine Fehlermeldung nach der anderen aus.
Kann es sein, dass so viele parallele Prozesse doch zuviel für ein Programm sind?
Speziell Nr. 2 ist problematisch. Denke, alle anderen Prozesse habe ich weitgehend im Griff.
Bei 2. läuft mir allerdings der Speicher immer voll. Wenn ich das Programm einige Minuten laufen lasse, braucht es fast genau so lange um beendet zu werden, was meine Vermutung mit dem Speicherüberlauf hervorruft.
Kann mir hierbei vielleicht irgendwer behilflich sein? Habe ich in der Syntax für die Schreibeprozedur irgendwelche Fehler gemacht? Ich grübel nun schon mehr als eine Woche an dem Problem, aber ich sitze hier wie der Ochs vorm Berg.
Lasse ich alle 5 Prozesse parallel laufen, so wird die Problematik deutlich beschleunigt. Wie man sieht, habe ich auch einen Indikator für die Zeit eines Schleifendurchlaufs eingebaut. Dieser zeigt mir, dass sich mit der Laufzeit auch jeder einzelne Schleifendurchlauf verlangsamt.
(04.10.2011 16:46 )Selectah schrieb: Speziell Nr. 2 ist problematisch. Denke, alle anderen Prozesse habe ich weitgehend im Griff.
Bei 2. läuft mir allerdings der Speicher immer voll. Wenn ich das Programm einige Minuten laufen lasse, braucht es fast genau so lange um beendet zu werden, was meine Vermutung mit dem Speicherüberlauf hervorruft.
Kann mir hierbei vielleicht irgendwer behilflich sein? Habe ich in der Syntax für die Schreibeprozedur irgendwelche Fehler gemacht? Ich grübel nun schon mehr als eine Woche an dem Problem, aber ich sitze hier wie der Ochs vorm Berg.
Lasse ich alle 5 Prozesse parallel laufen, so wird die Problematik deutlich beschleunigt. Wie man sieht, habe ich auch einen Indikator für die Zeit eines Schleifendurchlaufs eingebaut. Dieser zeigt mir, dass sich mit der Laufzeit auch jeder einzelne Schleifendurchlauf verlangsamt.
Hoffe, ich hab mich deutlich ausgedrückt.
Hallo Selectah,
hab Deine Vi´s nur kurz überflogen. OBTAIN Notifier oder OBTAIN Queue NIEMALS in die While-Schleife bzw. bei jeder Iteration ausführen (bei Dir im Sub-Vi "Config_DAQmx_write_ALL.vi").
Dadurch werden ständig neue Referenzen erzeugt die den Speicher zumüllen.
Also OBTAIN außerhalb der Schleife und die Referenz(en) weitergeben.
Es geht schon, es ist aber gefährlich. Wie rasta geschrieben hat, JEDES "Obtain Notifier" erzeugt eine Referenz, die auch Speicher belegt (bis zu 4k!), auch wenn natürlich jedes Mal auf denselben Melder verwiesen wird. Wenn du das sehr häufig (eben in einer Schleife machst), kannst du dir den Speicher zumüllen.
Deshalb ist es besser, nur einmal im Programm eine Melder-Referenz zu erstellen und diese dann per FGV oder auch notfalls per globaler Variable zu verteilen.
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!
@dimitri84: Ich glaube es sind die Interrupts, die dir das Leben schwer machen. Sowohl DAQmx als auch CAN lösen sie aus, der Prozessor kommt da anscheinend nicht mehr hinterher. Lösen lässt sich das nur durch weniger Interrupts, wofür zwei Wege bereitstehen. Entweder die Paketgröße erhöhen oder auf Hardware ausweichen, die DMA umsetzt. Die Karten der M-Serie haben glaube ich sechs DMA-Kanäle, während die X-Serie acht bietet. Die XNET-Karten bieten ebenfalls DMA an. Manchmal hilft es auch, ein Gerät per PCI und das zweite per PCIe anzubinden.