Home » Tutorials » Object Pascal/RTL » Parallelisierung mit Delphis Parallel Library

Parallelisierung mit Delphis Parallel Library

Parallele For-Schleife

Die einfachste Art der Parallelisierung gibt es nun für eine For-Schleife. Ein kleines Beispiel, das für die Zahlen von 2 bis 100.000 prüft, ob sie Primzahlen sind. Dabei wird für jede einzelne Zahl wiederum eine Schleife über alle kleineren Zahlen ausgeführt und geprüft, ob sich die Zahl ohne Rest teilen lässt. In Code sieht das so aus:

function IsPrime(N: Integer): Boolean;
var I: Integer;
begin
  for I := 2 to N - 1 do
    if (N mod I) = 0 then
      exit(false);
  result := true;
end;

Die äußere Schleife:

procedure Start;
var Total: integer;
  I: integer;
Begin
  Total := 0;
  for I := 1 to 100000 do
    Begin
    If IsPrime(I) then
      inc(Total);
  End;
  ShowMessage(IntToStr(Total) + ' Primzahlen gefunden');
end;

Führen wir die Anwendung aus, sollte ausgegeben werden, dass 9593 Primzahlen gefunden wurden.  Nun wollen wir natürlich wissen, wie lange diese Berechnung gedauert hat. Dazu kann TStopwatch verwendet werden:

uses System.Diagnostics;

procedure Start;
var Total: Integer;
  I: Integer;
  Watch: TStopwatch;
begin
  Total := 0;
  Watch := TStopwatch.Create;
  Watch.Start;
  For I := 1 to 100000 do
    Begin
    If IsPrime(I) Then
      inc(total);
  End;
  Watch.Stop;
  ShowMessage(IntToStr(Total) + ' Primzahlen gefunden, ' +
    IntToStr(Watch.ElapsedMilliseconds) + ' ms');
end;

Tests zeigen z.B., dass die Ausführung des Codes ungefähr 1500 Millisekunden benötigt. Das ist je nach Hardware-Ausstattung natürlich unterschiedlich.

Nun kommt die neue Parallel Library zum Einsatz und ersetzt die herkömmliche For-Schleife durch „TParallel.For“. Diese Methode benötigt in unserem Fall drei Parameter: Anfangs- und Endwert der Schleife (wie ja auch die bisherige Schleife) und als drittes eine anonyme Methode, die den auszuführenden Code enthält:

uses System.Threading;

...
  TParallel.For(1, 100000, procedure(I: Integer)
  Begin
    If IsPrime(i) Then
      inc(Total);
  End);
...

So unterschiedlich sieht der Code gar nicht aus. Führen wir ihn aus und befragen die Stoppuhr, ob sie denn einen Unterschied bemerkt. Und ja, das tut sie! Der gleiche Rechner, der im vorigen Beispiel ca. 1500 Millisekunden benötigt hat, ist nun schon nach ca. 370 Millisekunden fertig, weil nun auch seine anderen Kerne etwas zu tun haben.

Wie gesagt: Das hängt natürlich von der verwendeten Hardware ab. Aber es zeigt auf jeden Fall, dass man in diesem Fall die Rechenzeit deutlich verkürzen kann, ohne dass der Code wesentlich komplizierter aussieht.

Download Beispiel-Anwendung (Parallele For-Schleife, ZIP, 52 KB)

Ein Gedanke zu „Parallelisierung mit Delphis Parallel Library“

  1. In der Routine

      ...
      TParallel.For(1, 100000, procedure(I: Integer)
      Begin
        If IsPrime(i) Then
          inc(Total);
      End);
      ...

    würde ich statt inc(Total) die Anweisung TInterlocked.Increment(Total) verwenden, sonst stimmt die Anzahl der ermittelten Primzahlen nicht.

Kommentare sind geschlossen.