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/)
-   -   TParallels For-Schleife abbrechen (https://www.delphipraxis.net/196074-tparallels-schleife-abbrechen.html)

günni0 21. Apr 2018 01:19

TParallels For-Schleife abbrechen
 
Eben bin ich in den Genuss einer TParallel-For-Schleife gekommen. Aber leider weiß ich nicht wie man die abbricht.
Wenn meine Abbruchbedingung zutrifft dauert es noch mehrere Sekunden, also genau so lange wie die Schleife noch hätte durchlaufen müssen, bis wirklich Schluss ist


Delphi-Quellcode:
TParallel.For(0, FListLocal.Count - 1,
 procedure(i_parallel: Integer; LoopState: TParallel.TLoopState)
  begin
   if LoopCancelled then // wird von draußen gesetzt
    begin
     LoopState.Stop;
     Exit;
    end;

    .........
    ....
  end);
Reicht Stop und Exit nicht?

KodeZwerg 21. Apr 2018 06:28

AW: TParallels For-Schleife abbrechen
 
Ersetze doch spassenshalber das Exit mit Break oder Stop und sag was passiert.

Uwe Raabe 21. Apr 2018 08:34

AW: TParallels For-Schleife abbrechen
 
Bei einem TParallel.For laufen ja mehrere Iterationsschritte gleichzeitig ab. Mit dem LoopState.Stop bewirkst du nur, daß keine neuen Iterationen mehr gestartet werden. Die noch laufenden werden damit aber nicht abgebrochen. Wie viele Iterationen hat denn deine Schleife?

günni0 21. Apr 2018 10:24

AW: TParallels For-Schleife abbrechen
 
Exit und Stop bringen nichts. Break wird nicht akzeptiert vom Compiler.

Ich belasse es bei beim Standard. Das sind je nachdem 5 bis 15 die da erzeugt werden.
Sollte aber durch mein Exit der Code nach meiner Bedingung gar nicht erst ausgeführt werden wenn meine Bedingung zutrifft?

KodeZwerg 21. Apr 2018 10:38

AW: TParallels For-Schleife abbrechen
 
loopState.Break(); wird hier beschrieben zum abbruch. Klappt das mit Delphi?
edit
Danke übrigens mit dem Thread, kannte ich auch noch nicht, scheint echt eine tolle Möglichkeit zu sein alle CPU Kerne auszunutzen!

Uwe Raabe 21. Apr 2018 11:15

AW: TParallels For-Schleife abbrechen
 
Zitat:

Zitat von günni0 (Beitrag 1400055)
Ich belasse es bei beim Standard. Das sind je nachdem 5 bis 15 die da erzeugt werden.
Sollte aber durch mein Exit der Code nach meiner Bedingung gar nicht erst ausgeführt werden wenn meine Bedingung zutrifft?

TParallel.For teilt den von-bis Bereich in mehrere Happen auf und startet dann separate Tasks für jeden. In der Standardeinstellung sind das zweimal die Anzahl verfügbarer CPU-Kerne. Die Tasks starten dann mehr oder weniger gleichzeitig und es ist durchaus möglich, daß schon eine entsprechende Anzahl die Abfrage bereits negativ durchlaufen hat. Diese werden dann natürlich noch bis zum Ende ausgeführt. Im Worst Case wird die Abbruchbedingung erst dann gesetzt, wenn schon alle Iterationen darüber hinweg sind, und dann bringt das gar nichts.

Du kannst ja mal ausprobieren, die Bedingung schon vor dem Aufruf der For-Schleife zu setzen. Braucht es dann auch noch genauso lang? In dem Fall ist der Overhead für die Parallelisierung vermutlich höher als der Aufwand für die eigentliche Aufgabe. Dann wäre eine normale For-Schleife vielleicht die bessere Wahl.

günni0 21. Apr 2018 11:28

AW: TParallels For-Schleife abbrechen
 
Ohne diese parallele For-Schleife wird quasi sofort abgebrochen.
Das werden wohl einfach zu viele parallele For-Schleifen sein die da erstellt werden.

Setze ich eine eigene boolsche Variable noch vor die For-Schleife, setze diese im Block der Abbruchbedingung auf True und frage die danach ab nach dem Motto...
Delphi-Quellcode:
weiter := true
schleife von a bis 2

 wenn abbrechen dann
  begin
   weiter := false
   parallel.stop
   exit
  end

 if weiter dann
  ....
Klappt es auch relativ gut mit dem Abbrechen.

Schokohase 21. Apr 2018 12:33

AW: TParallels For-Schleife abbrechen
 
Lass mal diesen Code laufen:
Delphi-Quellcode:
program ParallelForBreak;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.Diagnostics,
  System.SysUtils,
  System.SyncObjs,
  System.Threading;

var
  s: string;
  sw: TStopwatch;
  ccount, wcount: Integer;
  r: TParallel.TLoopResult;

begin
  try
    ccount := 0;
    wcount := 0;

    sw := TStopwatch.StartNew( );

    r := TParallel.for( 1, 5000,
      procedure( idx: Integer; loopstate: TParallel.TLoopState )
      begin
        TInterlocked.Increment( ccount );

        if loopstate.ShouldExit then
          Exit;

        // Workload
        TInterlocked.Increment( wcount );
        Sleep( 1 );

        // Abbruchbedingung
        if idx = 3800 then
        begin
          loopstate.Break;
        end;
      end );

    sw.Stop( );

    WriteLn( 'LoopResult:' );
    WriteLn( ' Completed: ', r.Completed );
    Writeln( ' LowestBreakIteration: ', r.LowestBreakIteration );

    WriteLn( 'Statistics:' );
    WriteLn( ' IteratorEvent called: ', ccount );
    WriteLn( ' IteratorEvent processed: ', wcount );
    WriteLn( ' Execution time: : ', sw.ElapsedMilliseconds, ' ms' );

    ReadLn( s );
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
end.
Das Ergebnis hier:
Code:
LoopResult:
  Completed: FALSE
  LowestBreakIteration: 3800
Statistics:
  IteratorEvent called: 3984
  IteratorEvent processed: 3820
  Execution time: : 12799 ms
Soll bedeuten:
- Der IteratorEvent wurde 3984 mal aufgerufen
- Im IteratorEvent wurden 3820 Berechnungen ausgeführt
- Im IteratorEvent wurden somit 164 Berechnungen nicht ausgeführt (vorzeitig abgebrochen)

günni0 21. Apr 2018 12:36

AW: TParallels For-Schleife abbrechen
 
Abbruchbedingung ist 3800. Es wurde aber 3820 berechnet. Heißt das, dass es nicht wirklich zuverlässig ist eine TParallel zu verwenden?

Ich denke jedoch LoopState.ShouldExit hat mir geholfen.

Schokohase 21. Apr 2018 12:48

AW: TParallels For-Schleife abbrechen
 
Was ist daran nicht zuverlässig?

Willst du zuverlässig nur 3800 Aufrufe? Dann rufe es nur 3800 mal auf.

Oder sollen die Aufrufe solange erfolgen, bis man das passende Ergebnis gefunden hat? Dann ist es wurscht, ob es 3800 oder 3820 Aufrufe sind.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:51 Uhr.
Seite 1 von 2  1 2      

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