Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TParallel.&For Problem unter Windows (https://www.delphipraxis.net/202133-tparallel-problem-unter-windows.html)

ich2 1. Okt 2019 14:08

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:
TParallel.&For
zumindest habe ich den Fehler soweit eindampfen können, dass es irgendwas mit dem Multi-Threading zu tun hat.
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:
https://youtu.be/NwcdBmQBJ7w

-Anfang bis 1:38 [hier]: durch mehrfaches Ausführen werden jede Menge Threads erzeugt
-1:38-3:43 [hier]: warten bis Windows die Threads wieder rauswirft
-einmal gehts dann noch und danach ist die Software nicht mehr zu gebrauchen
-bei 4:31 [hier]: wird auf single-thread umgestellt...das funktioniert wieder
-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)

Sherlock 1. Okt 2019 14:56

AW: TParallel.&For Problem unter Windows
 
Hast du das mal ohne "&" versucht?

Sherlock

ich2 1. Okt 2019 15:05

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

ich2 1. Okt 2019 15:12

AW: TParallel.&For Problem unter Windows
 
...kleiner Fehler im Quellcode, der jedoch nichts an dem Effekt ändert:

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);
sollte natürlich heißen

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);

ich2 1. Okt 2019 15:44

AW: TParallel.&For Problem unter Windows
 
die weiteren Tests mit:

1) eigener Threadpool
2) begrenzen der verfügbaren Threads auf 1

Delphi-Quellcode:
Initialization
  testpool := TThreadpool.Create;
  testpool.SetMaxWorkerThreads ( 1 );
  testpool.SetMinWorkerThreads ( 1 );

Finalization
  testpool.Free;
sowie eigene storage-Variable innerhalb der &for-loop
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);

Der schöne Günther 1. Okt 2019 16:14

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.

ich2 1. Okt 2019 16:38

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:
z
sollte zu einem
Delphi-Quellcode:
_z
werden :wink:

Der schöne Günther 1. Okt 2019 16:46

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?

ich2 1. Okt 2019 17:24

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.

https://ep5.physik.uni-wuerzburg.de/...019_TParallel/

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... :?

Der schöne Günther 1. Okt 2019 17:31

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:
  • Es auf 10.0 keine Probleme gibt
  • Es auf 10.2.3 keine Probleme gibt
  • Es auf 10.3 Probleme gibt

Richtig?


Das klingt sogar wie folgendes Problem:
https://quality.embarcadero.com/browse/RSP-23837

Zitat:

The behaviour of TParallel.For has changed completely between 10.2.3 and 10.3.1. The peformance sems to have degraded, but worse than that it seems that under some conditions the performance of the thread pool deteriorates until it is worse than single-threading, and keeps adding more threads to the pool for no reason.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:25 Uhr.
Seite 1 von 2  1 2   

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