Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TParallel.for innerhalb iTask (https://www.delphipraxis.net/201663-tparallel-innerhalb-itask.html)

ich2 12. Aug 2019 22:44

TParallel.for innerhalb iTask
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

mir ist da etwas merkwürdiges aufgefallen und da wollte ich mal in die Runde fragen...

Hintergrund ist folgender: per Webcam wird ein Videostream verarbeitet, wobei dabei mehrere Filter und so weiter über die Einzelbilder geschmissen werden. Damit das ganze flott läuft sind die Filter oftmals mit TParallel.for Schleifen versehen.
Parallel zu der Bildverarbeitung läuft noch ein Scripting-Tool, welches u.a. auf externe Geräte zugreift.
Damit es nicht zu unnötigen Kollisionen und ruckeliger GUI kommt, wird das Script innerhalb einer Task abgearbeitet.
Über das Script nun werden dann auch Funktionen für die Datenauswertung verwendet, welche wiederum mit TParallel.For Schleifen beschleunigt werden.

Das ganze läuft soweit eigentlich ganz gut...aber nach einiger Zeit wird das ganze System immer träger und schließlich dauern die Bearbeitungsschritte immer länger...ein Blick in den Process Explorer zeigt, dass es nicht am Speicher liegt, sondern an der immer weiter wachsenden Anzahl an Threads, welche zu dem Programm gehören.

Also dann mal schnell ein Test (siehe unten) aufgesetzt und tatsächlich:
wenn zu schnell versucht wird, die Tasks aufzurufen bevor die Arbeit gemacht ist, dann kommen immer mehr Threads dazu...

Jetzt die Frage...was kann man dagegen tun?

besten Dank

jfheins 13. Aug 2019 07:38

AW: TParallel.for innerhalb iTask
 
Es gibt da so ein Sprichwort: Wenn du versuchst, ein Problem mit Thread zu lösen, hast du danach zwei Probleme.

Zu deinen Problemen: Wenn du eine geringfügig höhere Latenz verkraft kannst, würde ich die Bildverarbeitung single-threaded machen. Du bekommst ohnehin alle 16ms ein neues Bild, du kannst dann jedes Bild in einem neuen Task bearbeiten.

Alternativ kannst du auf einen anderen Threadpool umsteigen, bei SO hatte wohl auch jemand Probleme mit TParallel.For, vielleicht hilft dir die OmniThreadLibrary weiter ;-)

Der schöne Günther 13. Aug 2019 08:26

AW: TParallel.for innerhalb iTask
 
Was genau soll dein Beispiel-Quellcode verdeutlichen? Egal auf welchen Buttons ich herumpatsche, ich bekomme nie mehr als vier Worker-Threads. Das hätte ich auch erwartet.

Was auch immer dein "Scripting-Tool" ist - Bist du sicher dass das nicht von daher kommt? Was sagt dein "richtiges" Programm wenn es im Debugger läuft?

Moombas 13. Aug 2019 08:45

AW: TParallel.for innerhalb iTask
 
Zitat:

Zitat von ich2 (Beitrag 1441049)
...wenn zu schnell versucht wird, die Tasks aufzurufen bevor die Arbeit gemacht ist, dann kommen immer mehr Threads dazu...

Eigentlich schreibst du doch genau in diesem Satz, was das Problem ist.
Wieso verhinderst du nicht, das neue Threads gestartet werden, wenn noch andere laufen bzw. die mit ihrer Arbeit noch nicht fertig sind?

Ist ja logisch, das sich das dann gegenseitig immer mehr aufbaut (stark vereinfacht):

Thread 1 gestartet
Prozessoren bearbeiten 1 Thread
Thread 1 noch nicht fertig, aber nächster wird gestartet.
Prozessoren bearbeiten 2 Threads
Thread 1 und 2 noch nicht fertig, aber nächster wird gestartet.
Prozessoren bearbeiten 3 Threads
...

ggf. wird zwischendurch mal ein Thread fertig aber wenn der 1. Thread schon nicht fertig wird, bevor der zweite startet, wie sollen zwei Threads da fertig werden bevor der dritte startet usw.?

Richtig wäre:

...
Thread 1 gestartet
Prozessoren bearbeiten 1 Thread
Ein neuer Thread soll gestartet werden aber Thread 1 noch nicht fertig, daher noch keinen weiteren starten.
Prozessoren bearbeiten 1 Thread
Thread 1 fertig, nun kann der nächste gestartet werden.
Prozessoren bearbeiten 1 Thread
...

p80286 13. Aug 2019 09:35

AW: TParallel.for innerhalb iTask
 
Ganz so sparsam wäre ich nicht, zwei oder drei oder... Threads würde ich mir schon erlauben. Nur steigt dann natürlich der Verwaltungsaufwand und damit der Testaufwand. Da muß man sich dann fragen ob sich das lohnt.

Gruß
K-H

Moombas 13. Aug 2019 09:50

AW: TParallel.for innerhalb iTask
 
Zitat:

Zitat von p80286 (Beitrag 1441115)
Ganz so sparsam wäre ich nicht, zwei oder drei oder... Threads würde ich mir schon erlauben. Nur steigt dann natürlich der Verwaltungsaufwand und damit der Testaufwand. Da muss man sich dann fragen ob sich das lohnt.

Gruß
K-H

War ja auch nur ein Beispiel, da müsste man sich dann halt irgendein Limit setzen.
Es ging dabei nur um die Darstellung, das sich das so (wie er es aktuell hat) natürlich auftürmen würde.

Bezüglich Verwaltungsaufwand: Könnte man recht simpel über einen "Flag" (in welcher Form auch immer) lösen, dann braucht man nicht immer nach den Threads "suchen".

ich2 13. Aug 2019 10:20

AW: TParallel.for innerhalb iTask
 
Vielen Dank für die schnellen Antworten.

Ja...ein Thread kommt...zwei Probleme sind da ;)

Im Grunde ist es klar, dass man natürlich einen Thread abarbeiten lassen muss und dann einen neuen (oder besser denselben) wieder verwendet und mit einer neuen Aufgabe füttert. Leider geht da aus meiner Sicht der Sinn verloren.
Ich möchte natürlich gerade auch parallel arbeiten lassen :)
Mein Problem ist gerade, dass obwohl die Aufgaben fertig gerechnet sind immer wieder neue Threads erstellt werden, anstatt die 'alten' wiederverwendet und diese sich dann ansammeln.

@Der schöne Günther
einfach mal einen Stein auf die Enter-Taste legen und zuschauen, wie sich die Threads sammeln...siehe Video

https://youtu.be/9hy6n6oCzPs

Die Frage ist, wie man die Threads wieder los wird...?

p80286 13. Aug 2019 13:21

AW: TParallel.for innerhalb iTask
 
Delphi-Quellcode:
.FreeOnTerminate
?

Gruß
K-H

Schokohase 13. Aug 2019 13:23

AW: TParallel.for innerhalb iTask
 
Zitat:

Zitat von p80286 (Beitrag 1441148)
Delphi-Quellcode:
.FreeOnTerminate
?

Was man dann wo und wie einbaut?

Bislang dachte ich immer diese Worker-Threads werden vom Threadpool verwaltet, aber ich lerne gerne dazu ...

ich2 18. Aug 2019 23:00

AW: TParallel.for innerhalb iTask
 
...das oben beschriebene Problem tritt tatsächlich unter Windows 7 nicht auf und ist mir erst beim Umstieg auf Windows 10 aufgefallen.
Mit einem dedizierten Threadpool lässt sich dieses Phänomen in den Griff bekommen :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:43 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz