![]() |
TParallel.&For Problem unter Windows
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen...
ich habe ein Problem mit der Parallelisierung in Delphi/Firemonkey:
Delphi-Quellcode:
zumindest habe ich den Fehler soweit eindampfen können, dass es irgendwas mit dem Multi-Threading zu tun hat.
TParallel.&For
Hintergrund ist, dass ich an einem größeren Projekt arbeite, bei dem es mehrere Parallelisierungsschritte gibt, welche den Ablauf beschleunigen. Dabei ist ein merkwürdiger Fehler aufgetreten: alles funktioniert erstmal ganz toll, aber nach einer gewissen Zeit scheint sich die Software aufzuhängen...also besser gesagt sie verliert extrem an Leistung. Ein erster Blick in den Taskmanager unter Details zeigt, dass die Anzahl der Threads anfangs steigt und steigt...was an sich wohl kein Problem zu sein scheint, dann jedoch nach einer gewissen Zeit, wo man die Software z.B. im Hintergrund laufen lässt, gibt Windows die Threads wieder frei...soweit so gut. Danach jedoch scheint die Parallelisierung nicht mehr zu tun...und braucht extrem viel länger... um den Fehler zu reproduzieren und nachvollziehen zu können, ist einmal der Quellcode angehängt und auch ein Video im Link zu finden: ![]() -Anfang bis 1:38 [ ![]() -1:38-3:43 [ ![]() -einmal gehts dann noch und danach ist die Software nicht mehr zu gebrauchen -bei 4:31 [ ![]() -danach wider auf MT und wieder weg...dauert sogar noch länger... Vielleicht hat ja jemand eine Idee was denn da schief läuft...? Danke schonmal *getestet auf zwei Rechner mit je Windows 10 Pro 1903 *kompiliert mit Rad Studio 10.3 Community Edition (ebenfalls getestet mit Rad Studio 10.1 Pro) |
AW: TParallel.&For Problem unter Windows
Hast du das mal ohne "&" versucht?
Sherlock |
AW: TParallel.&For Problem unter Windows
Hallo Sherlock,
es sollte kein Unterschied zwischen for und &for geben...das &-Zeichen ist für die Unterscheidung zur normalen for-loop. ...ein Test zeigte aber den gleichen Effekt Grüße |
AW: TParallel.&For Problem unter Windows
...kleiner Fehler im Quellcode, der jedoch nichts an dem Effekt ändert:
Delphi-Quellcode:
sollte natürlich heißen
TParallel.&For ( 0, s1-1, procedure ( _zz: Integer )
var _xx, _yy: Integer; begin for _yy := 0 to s1-1 do for _xx := 0 to s1-1 do testdata [ zz, yy, xx ] := random; end);
Delphi-Quellcode:
TParallel.&For ( 0, s1-1, procedure ( _zz: Integer )
var _xx, _yy: Integer; begin for _yy := 0 to s1-1 do for _xx := 0 to s1-1 do testdata [ _zz, _yy, _xx ] := random; end); |
AW: TParallel.&For Problem unter Windows
die weiteren Tests mit:
1) eigener Threadpool 2) begrenzen der verfügbaren Threads auf 1
Delphi-Quellcode:
sowie eigene storage-Variable innerhalb der &for-loop
Initialization
testpool := TThreadpool.Create; testpool.SetMaxWorkerThreads ( 1 ); testpool.SetMinWorkerThreads ( 1 ); Finalization testpool.Free; und sogar nur eine lokale Abarbeitung führen immer zum gleichen Problem
Delphi-Quellcode:
TParallel.&For ( 0, s1-1, procedure ( _zz: Integer )
var _s, _xx, _yy: Integer; _r: Real; begin _s := s1; for _yy := 0 to _s-1 do for _xx := 0 to _s-1 do _r := _xx*_yy;//testdata [ _zz, _yy, _xx ] := random; end, testpool); |
AW: TParallel.&For Problem unter Windows
Das ändert sehr wohl was.
Ergebnisse auf meinem Rechner. Dein Quelltext 1:1 übernommen: Multithreaded: 4430 ms total Singlethreaded: 1085 ms total Closure berichtigt sodass die Schleifenvariablen _yy und _xx in der lokalen Methode liegen und nicht "außerhalb": Multithreaded: 2020 ms total Singlethreaded: 810 ms total Random() gegen feste Zuweisung ersetzt: Multithreaded: 447 ms total Singlethreaded: 1100 ms total (wtf) Von Debug 64 Bit auf Release-Fassung 64 Bit gewechselt: Multithreaded: 225 ms Singlethreaded: 590 ms
Delphi-Quellcode:
unit Unit1;
interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Diagnostics, System.Threading, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit, FMX.EditBox, FMX.SpinBox, FMX.Layouts, FMX.ListBox, FMX.StdCtrls, FMX.Controls.Presentation; type T3DFloatArray = TArray<TArray<TArray<Double>>>; TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; SpinBox1: TSpinBox; SpinBox2: TSpinBox; isMultiThreadedCheckbox: TCheckBox; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private var stopwatch1, stopwatch2: TStopWatch; private class function NotRandom(): Double; inline; end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.Button1Click(Sender: TObject); var testDataDimensionCount: Integer; iterationCount: Integer; count, zz: Integer; testdata: T3DFloatArray; testProcedure: TProc<Integer>; begin testDataDimensionCount := Round(SpinBox1.Value); iterationCount := Round(SpinBox2.Value); ListBox1.Clear(); stopwatch1 := TStopwatch.StartNew(); setlength(testdata, testDataDimensionCount, testDataDimensionCount, testDataDimensionCount); stopwatch1.Stop(); ListBox1.Items.Add('get-mem: ' + inttostr(stopwatch1.ElapsedMilliseconds) + ' ms'); testProcedure := procedure(_zz: Integer) var _xx, _yy: Integer; begin for _yy := 0 to testDataDimensionCount - 1 do for _xx := 0 to testDataDimensionCount - 1 do testdata[zz, _yy, _xx] := NotRandom(); end; stopwatch2 := TStopwatch.StartNew(); for count := 0 to iterationCount - 1 do begin stopwatch1 := TStopwatch.StartNew(); if isMultiThreadedCheckbox.IsChecked then begin TParallel.&For( 0, testDataDimensionCount - 1, testProcedure ); end else begin for zz := 0 to testDataDimensionCount - 1 do testProcedure(zz); end; stopwatch1.Stop(); ListBox1.Items.Add('[' + inttostr(count) + ']: ' + inttostr(stopwatch1.ElapsedMilliseconds) + ' ms'); end; stopwatch2.Stop; ListBox1.Items.Add('-> done: ' + inttostr(stopwatch2.ElapsedMilliseconds) + ' ms'); end; procedure TForm1.FormCreate(Sender: TObject); begin randomize; end; class function TForm1.NotRandom(): Double; begin Result := 42.0; end; end. |
AW: TParallel.&For Problem unter Windows
Hallo Günther,
danke fürs Probieren... das Problem ist hier gar nicht die Geschwindigkeit, es ist klar, dass gewisse Einstellungen die Geschwindigkeit erhöhen... es ist vielmehr, dass die Software nach einer Weile (Nichtbenutzung) (siehe Video) extrem langsam wird. es scheint eine Sache von Windows zu sein, dein Quellcode, sowie FMX/VCL Umgebung...überall das gleiche...wenn Multithreading im Spiel ist, dann funktioniert die Software nach einer bestimmten Wartezeit nicht mehr korrekt. wenn man sich den Taskmanager anschaut, dann erkennt man den Zeitpunkt: nach einer gewissen 'nichtbenutzen'-Zeit werden die Threads freigegeben und danach geht nichts mehr. kann irgendjemand diesen Effekt reproduzieren...? p.s.: die Variable
Delphi-Quellcode:
sollte zu einem
z
Delphi-Quellcode:
werden :wink:
_z
|
AW: TParallel.&For Problem unter Windows
Ok, ich wollte aufzeigen dass die Closure und Random() die Geschwindigkeit in den Keller ziehen.
Ich muss aber ganz ehrlich sagen ich verstehe dein konkretes Problem noch nicht. Getestet mit 10.0 Seattle, aber man kann machen was man möchte, die Speicherauslastung und Rechenzeit bleibt konstant. So harte Aufhänger wie bei dir im Video bekomme ich niemals hin. Interessant wäre doch mal, hier im Debugger anzuhalten und zu schauen wo es hängt? |
AW: TParallel.&For Problem unter Windows
Hallo zusammen...
also gut...ich denke ich habe den Fehler gefunden...und es ist sehr interessant und vor allem nervig... es ist der Compiler von der Community Edition...der macht komische Sachen. ![]() unter dem Link findet ihr 3 Versionen, welche mit unterschiedlichen compilern und auf win7 und win10 erstellt wurden...nur die communityedition-Version erzeugt den beschriebenen Effekt... schade um die Zeit... :? |
AW: TParallel.&For Problem unter Windows
Auf welchem Betriebssystem das kompiliert wird sollte keinen Unterschied machen.
Ich glaube ehrlich gesagt auch nicht dass es einen Unterschied macht ob Professional, Enterprise oder Community-Edition. Wir sehen bislang dass:
Richtig? Das klingt sogar wie folgendes Problem: ![]() Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz