LabVIEWForum.de
Parallelisierung von DLLs - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+--- Thema: Parallelisierung von DLLs (/Thread-Parallelisierung-von-DLLs)

Seiten: 1 2


Parallelisierung von DLLs - Herm - 19.07.2012 14:07

Hallo

Ich habe folgendes Problem:
Ich nehme mit einer Kamera von Image Control Bilder auf. Diese Bilder werden an eine Bildauswertung angeschlossen. Die Auswertung liegt in Form einer DLL vor und wird über einen CLF-Knoten eingebunden. Das Ganze funktioniert an sich auch, nur ist die DLL deutlich langsamer, als die Kamera Bilder liefert. Ich möchte also die Bilder auf mehrere CLF-Knoten aufteilen, die dann in unterschiedlichen Kernen abgearbeitet werden. Der PC, den ich benutze hat 8 Kerne und 16 GB Arbeitsspeicher. Ich will maximal 4 Kerne mit der Abarbeitung der DLL belasten. Dazu möchte ich quasi einen Kreislauf schreiben. Die Bilder der Kamera werden in einer lossy queue abgelegt. Immer wenn eine DLL ein Bild bearbeitet hat soll sie ein TRUE ausgeben, welches der lossy queue sagt, dass es jetzt ein weiteres Bild ausgeben kann ("Element auslesen" von VI "Queue-Status lesen" auf TRUE setzten).

Je nach Größe des Bildes und Auswertungsmethodik (es gibt zwei verschiedene) braucht die DLL zwischen 66 und 200 ms. Wenn nur kleine Bilder vorliegen, die schnell ausgewertet werden, sollen auch nur 1-2 DLLs und damit Kerne belastet werden, wenn die DLLs länger brauchen, soll die Auswertung automatisch auf die anderen DLLs erweitert werden. Die DLLs sollen also priorisiert angesteuert werden. Immer wenn die erste frei ist, soll diese auch mit dem neuen Bild belegt werden und nur, wenn diese gerade arbeitet, soll das Bild an die zweite gegeben werden usw. Wenn alle 4 DLLs belegt sind und neue Bilder ankommen, verfallen diese automatisch durch die lossy queue.
Ich habe das Prinzip des VIs vereinfacht angehängt, so wie es mit einer DLL aussehen würde. Das eingehende Bild wird durch einen einzelnen Zufallswert dargestellt. Die DLL habe ich mal vereinfacht dargestellt als Timer mit 66 ms Wartezeit (Mindestlaufzeit der DLL) und der eingehende Wert wird um 1 erhöht.

Hier also meine Frage:
Wie lässt sich sozusagen eine priorisierende Casestruktur realisieren, oder etwas, was die Bilder bevorzugt auf bestimmte Schleifen aufteilt. Wenn ich einfach einen Counter durchlaufen lasse, der mir der Reihe nach die Bilder in die unterschiedlichen DLLs schickt, dann werden immer alle 4 Kerne belastet, obwohl das nicht unbedingt nötig ist. Ich möchte ja hier, dass die 1. DLL priorisiert behandelt wird, nur wenn diese gerade ein Bild bearbeitet, soll die nächste DLL verwendet werden.

Viele Grüße

Herm


RE: Parallelisierung von DLLs - Herm - 25.07.2012 13:04

Hallo,

hat zu meinem Prolem keiner eine Idee, oder habe ich mich bei der Beschreibung zu undeutlich ausgedrückt?

Gruß

Herm


RE: Parallelisierung von DLLs - GerdW - 25.07.2012 21:55

Hallo Herm,

Zitat:welches der lossy queue sagt, dass es jetzt ein weiteres Bild ausgeben kann ("Element auslesen" von VI "Queue-Status lesen" auf TRUE setzten)
Das klingt für mich nach einer RaceCondition, wenn mehrere Prozesse sich Daten aus der Queue holen sollen: Es könnte passieren, das gleichzeitig zwei parallele "DLL"-Routinen sich auf die gleiche Weise sich die Elemente in der Queue ausgeben lassen und dann das gleiche Bild analysieren... Daten immer per DeQueue aus der Queue auslesen!

Vorschlag:
- Steuer die parallelen Routinen über die Anzahl der in der Queue gespeicherten Daten: sind nur wenige Daten enthalten, laufen nur 1 oder 2 Routinen. Werden es mehr als 10 Elemente, darf die 3. Routine helfen. Liegen mehr als 20 Elemente in der Queue, greift die 4. Routine ein. Und immer Daten per DeQueue abfragen!!!
- Erlaubt die DLL überhaupt parallele Zugriffe auf die gleiche Funktion?


RE: Parallelisierung von DLLs - rolfk - 25.07.2012 22:22

(25.07.2012 13:04 )Herm schrieb:  Hallo,

hat zu meinem Prolem keiner eine Idee, oder habe ich mich bei der Beschreibung zu undeutlich ausgedrückt?

Gruß

Herm

Deine Idee ist zwar technisch brilliant aber ein Alptraum zum implementieren. LabVIEW ist nicht dazu gedacht um solche komplexen Multithreadingkonfiguration durchzuführen. LabVIEW macht vieles automatisch was in 95% von den Fällen von Vorteil ist aber in Deinem Fall nicht die notwendigen Konfigurationsmöglichkeiten lässt.

Das Ganze lässt sich in C schon machen, aber ist ein ziemlich komplexes Problem zum Lösen bei dem sich selbst gestandene Multithreadingprogrammierer gehörig die Zähne ausbeissen würden. Den in C kannst Du zwar alles machen aber es macht 0.0% davon automatisch.


RE: Parallelisierung von DLLs - Herm - 26.07.2012 09:46

(25.07.2012 21:55 )GerdW schrieb:  
Zitat:Das klingt für mich nach einer RaceCondition, wenn mehrere Prozesse sich Daten aus der Queue holen sollen: Es könnte passieren, das gleichzeitig zwei parallele "DLL"-Routinen sich auf die gleiche Weise sich die Elemente in der Queue ausgeben lassen und dann das gleiche Bild analysieren... Daten immer per DeQueue aus der Queue auslesen!

Das Problem ist mir auch schon aufgefallen. DeQueue ist da eine gute Idee, danke.

Zitat:Vorschlag:
- Steuer die parallelen Routinen über die Anzahl der in der Queue gespeicherten Daten: sind nur wenige Daten enthalten, laufen nur 1 oder 2 Routinen. Werden es mehr als 10 Elemente, darf die 3. Routine helfen. Liegen mehr als 20 Elemente in der Queue, greift die 4. Routine ein. Und immer Daten per DeQueue abfragen!!!

Wenn ich DeQueue verwende, wird der Eintrag ja direkt wieder aus der Queue entfernt, da ich ihn ja direkt wieder auslese und dann lösche. So habe ich immer nur ein Element in meiner Queue drin. Dann funktioniert das nicht, dass ich meine Routinen in Abhängigkeit von der Anzahl der Elemente innerhalb der Queue steuere, oder irre ich mich da. Da kann ich ja nur Queue-Status lesen verwenden, nur habe ich dann wieder das Problem, dass mehrere Routinen denselben Wert verwenden können.

Zitat:- Erlaubt die DLL überhaupt parallele Zugriffe auf die gleiche Funktion?

Darüber habe ich mir noch garkeine Gedanken gemacht. Ich kenne mich mit DLLs nur soweit aus, dass ich sie in LabVIEW einbinden kann. Die Algorithmen habe ich nicht selbst geschrieben. Ist aber ein guter Hinweis, da muss ich mal nachforschen.


RE: Parallelisierung von DLLs - Herm - 26.07.2012 10:54

Wie im Beispiel könnte es funktionieren, ich erhalte immer ein true wenn eine Schleife abgearbeitet ist und übergebe das true an die Queue und die Nummer der fertigen Schleife an die darauffolgende Casestruktur. So wird das aktuelle Element immer in die freie Routine geschrieben. Schön wäre es zwar noch, wenn ich die Ergebnisse auch in der Reihenfolge raus kriege, wie sie geliefert werden. Das wäre für eine Bildanzeige wichtig, da sonst die Bilder dauernd wechseln, weil sie in einer anderen Reihenfolge ausgegeben werden, aber für statistische Zwecke ist das egal.
Das Problem ist jetzt noch, dass zwei oder mehrere Routinen denselben Wert übergeben bekommen können, wenn sie gleichzeitig fertig sind. Ab da würden sie immer denselben Wert erhalten, weil sie ab da immer gleichzeitig fertig werden. Oder verhindert das die Casestruktur, die die Daten zuweist?

PS: eigentlich wollte ich das in den Eintrag davor editieren, aber das geht wohl nur innerhalb von 10 Minuten.


RE: Parallelisierung von DLLs - GerdW - 26.07.2012 11:22

Hallo Herm,

Zitat:Wenn ich DeQueue verwende, wird der Eintrag ja direkt wieder aus der Queue entfernt, da ich ihn ja direkt wieder auslese und dann lösche. So habe ich immer nur ein Element in meiner Queue drin.
Falsch!
Wenn schneller Elemente in die Queue geschrieben als aus dieser entnommen werden, wird die Anzahl der Elemente in der Queue anwachsen. Genau das ist doch bei dir der Fall!? Deine DLL verarbeitet die Bilder langsamer, als sie von der Kamera kommen: also werden sich Bilder in der Queue ansammeln. Damit hast du ein Kriterium, um weitere Auswerteroutinen parallel zu starten...


RE: Parallelisierung von DLLs - Herm - 26.07.2012 13:42

Zitat:Falsch!
Wenn schneller Elemente in die Queue geschrieben als aus dieser entnommen werden, wird die Anzahl der Elemente in der Queue anwachsen. Genau das ist doch bei dir der Fall!? Deine DLL verarbeitet die Bilder langsamer, als sie von der Kamera kommen: also werden sich Bilder in der Queue ansammeln. Damit hast du ein Kriterium, um weitere Auswerteroutinen parallel zu starten...

Bei mir wird der Wert aus der Queue direkt entnommen. So ist immer nur ein Wert in der Queue. Wenn der Wert nicht weiter gereicht werden kann, wird er einfach gelöscht.

Aber im Prinzip sollte die Casestruktur schon verhindern, dass derselbe Wert in mehrere Routinen geschrieben wird. Es können ja nicht mehrere cases derselben Struktur ausgeführt werden.


RE: Parallelisierung von DLLs - Herm - 20.08.2012 14:43

Mir ist noch ein anderes Problem aufgefallen.
Ich habe das VI jetzt soweit modifiziert, dass ich jedes Bild mit einem Zeitstempel versehe und am Ende dann die ausgewerteten Bilder durch diesen Zeitstempel in der richtigen Reihenfolge anordnen kann. Dann ist egal, in welcher Reihenfolge die Bilder abgearbeitet werden.
Wenn ich jetzt jedoch relativ langsam Bilder geliefert bekomme, weil bspw. die fps erniedrigt werden, dann bleiben meine Schleifen einfach stehen. Da die "Bereitschaft" der Schleifen, dass sie neue Bilder auswerten können, nicht gespeichert werden, beenden sich die Schleifen, sobald kein neuer Wert mehr in der Eingangsque steht. Wenn ich also die Bilder schnell auswerte aber nur sehr wenige Bilder pro Sekunde bekomme, hört mein ganzes Programm nach kurzer Zeit auf. Ich habe jetzt eine weiter queue dazwischengesetzt, die mir quasi die Verfügbarkeiten speichert.
Nur sind in dieser queue immer die Werte aller vier Schleifen enthalten. Eigentlich sollten die Schleifen 0, 2 und 3 (Wartezeit von 66 ms) viel häufiger angesprochen werden, als die 2 (wartezeit von 1000 ms). Es laufen aber alle vier gleich schnell ab, die drei schnelleren warten auf die langsamere und laufen erst dann weiter. Ich wollte es eigentlich so haben, dass alle so schnell laufen, wie sie können.
Könnt ihr mir da weiterhelfen?


Gruß

Herm


RE: Parallelisierung von DLLs - GerdW - 20.08.2012 15:00

Hallo Herm,

deine Erzeugerschleife sieht schon sehr "kompliziert" aus.
Wozu schreibst du in eine Queue, um dann in der gleichen Schleife und sofort danach wieder aus dieser Queue auszulesen??? Warum dann nicht einfach einen Draht nehmen? Außerdem verteilst du munter "Bilder" an alle Verbraucherschleife, egal, wie schnell diese die Daten abarbeiten...

Überlege mal selbst, ob du das nicht einfacher hinbekommst...