Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi XE 7 - Parallel Programming Library (https://www.delphipraxis.net/181678-xe-7-parallel-programming-library.html)

Alex_ITA01 2. Sep 2014 15:18

XE 7 - Parallel Programming Library
 
Hallo zusammen,
ich weiß,XE7 ist heute erst rausgekommen aber vielleicht füllt sich ja der Thread dadurch in den nächsten Tagen ;-)

Wollte mich mal schlau machen, wie das "Parallel Programming Library" in XE7 aussieht.
Muss man da nur etwas einbinden damit es "von selber" so abläuft?
Muss man da etwas an seinem Programmen anpassen damit es überhaupt funktionieren kann?

Vielleicht schreibt hier mal einer rein, der es ausprobiert hat oder weiß wie es genau funktioniert ;-)

Viele Grüße

mkinzler 2. Sep 2014 15:23

AW: XE 7 - Parallel Programming Library
 
Von allein geht es nicht. Kann ja auch nicht funktionieren. Der Programmierer muss natürlich festlegen, was parallel abgearbeitet werden kann bzw. was unbedingt sequentiell.

https://www.youtube.com/embed/Ni3JDx...de=transparent

Der schöne Günther 2. Sep 2014 15:28

AW: XE 7 - Parallel Programming Library
 
Darauf bin ich auch ziemlich gespannt, aber das DocWiki zum Thema ist noch leer. Mehr als dieses 38-sekündige Promovideo kenne ich auch nicht.

Aber dazu kommt bei Embarcaderos Skill Sprints hoffentlich bald was :)

Alex_ITA01 2. Sep 2014 15:33

AW: XE 7 - Parallel Programming Library
 
Ich frage mich folgendes:

Angenommen ich habe 50 Threads (einfach eine in den Raum gestellte Zahl die keiner weiteren Nachfrage und Sinnhaftigkeit bedarf), die alle unabhängig voneinander etwas tun und irgendwann fertig werden können bzw. immer irgendwelche Sachen abarbeiten.
Dies kann ich ja jetzt aktuell nicht wirklich beeinflussen, auf wie viele Kerne das ausgelagert wird, damit es parallel erfolgen kann.

Bringt mir für diesen Anwendungsfall das "Parallel Programming Library" auch etwas?

Viele Grüße

mkinzler 2. Sep 2014 15:41

AW: XE 7 - Parallel Programming Library
 
Der Code zum Demo:http://sourceforge.net/p/radstudiode...llel%20Library

Jein. Mit der Bibliothek legst Du fest, welcher Code parallel ausgeführt werden kann. Wenn genügend Ressourcen (Kerne) vorhanden sind, laufen dann alle "Threads" parallel. Sonst halt so viele wie gehen und die anderen nach Abschluss einer anderen Aufgabe.

Dejan Vu 2. Sep 2014 15:49

AW: XE 7 - Parallel Programming Library
 
Bei C# kann man mit PLINQ einfach Schleifenoperationen parallel durchführen. Also: Gib mir mal aus der Liste alle Elemente mit X>3, sortiere nach Name.
Code:
var q = List.Where (l=>l.x>3).OrderBy(l=>l.Name);
foreach (var item in q) ...
// ==>
var q = List.AsParallel.Where (l=>l.x>3).OrderBy(l=>l.Name).Take(10).Sum(l=>l.z);
foreach (var item in q) ... <--- Abarbeitung in Threads und parallel
D.h. etwas aufzählbares wird so aufbereitet ('AsParallel'), das Threads damit parallel klarkommen.

Ich gehe mal davon aus, das die Parallel-Library von Emba auch so ähnlich funktioniert. Threads an sich kann man ja schon programmieren und hier wird es kaum einen Einsatz geben. Nur noch ohne LINQ, aber das ist hier zweitrangig.

Ergo wird sich der Mehrwert dadurch ergeben, das Du es bei Schleifen dem Framework überlässt, die Aufgaben an Threads zu verteilen. Windows wird dann die Verteilung auf die Kerne schon selbst übernehmen. An sich eine großartige Sache.

Jetzt noch LINQ für Delphi... :mrgreen:

PS: @mkinzler - kein Code im Link.. noch nicht.

Sir Rufo 2. Sep 2014 15:52

AW: XE 7 - Parallel Programming Library
 
Zitat:

Zitat von Alex_ITA01 (Beitrag 1270724)
Ich frage mich folgendes:

Angenommen ich habe 50 Threads (einfach eine in den Raum gestellte Zahl die keiner weiteren Nachfrage und Sinnhaftigkeit bedarf), die alle unabhängig voneinander etwas tun und irgendwann fertig werden können bzw. immer irgendwelche Sachen abarbeiten.
Dies kann ich ja jetzt aktuell nicht wirklich beeinflussen, auf wie viele Kerne das ausgelagert wird, damit es parallel erfolgen kann.

Das macht das Betriebssystem automatisch für dich. Du musst nur darauf achten, dass du die Ressourcen (hier z.B. CPU-Kerne) nicht "überlastest".

Wenn du in deinen 50 Threads sehr CPU-instensiven Code laufen lässt, dann bremst du deinen Rechner aus, sprich es wird langsamer.
Darum ist es besser, diese Verarbeitung immer nur mit <Anzahl-CPU-Kerne> Threads zu verarbeiten.

Wenn du in deinen 50 Threads Daten aus dem Internet holen möchtest, dann kann das je nach Internet-Anbindung gut oder schlecht sein.

mquadrat 2. Sep 2014 15:53

AW: XE 7 - Parallel Programming Library
 
Gibts dann eigentlich auch ein "await" ? Hatte angefangen mir das selber zu schreiben, aber fertig wäre das natürlich schöner.

Der schöne Günther 2. Sep 2014 15:54

AW: XE 7 - Parallel Programming Library
 
Zitat:

Zitat von Dejan Vu (Beitrag 1270727)
PS: @mkinzler - kein Code im Link.. noch nicht.

Nein, nicht mehr. Ist in den letzten Minuten wohl aus dem Branch in den Trunk gewandert:

svn://svn.code.sf.net/p/radstudiodemos/code/trunk/Object Pascal/RTL/Parallel Library

Schlau werde ich aus einem Haufen hunderter unkommentierter Zeilen aber spontan auch nicht.

Dejan Vu 2. Sep 2014 16:07

AW: XE 7 - Parallel Programming Library
 
Im Video hat man kurz gesehen, das aus einer 'Liste' eine parallel abarbeitbare (watn Wort) Enumeration wird. Ähnlich, wie ich das beschrieben habe: Die ForEach-Methode verteilt die Liste an Threads und jeder führt die Action für einzelne Elmente aus. Also irgendwie so jedenfalls. Das Relevante sind aber nur ein paar wenige Zeilen. Edit: Eigentlich nur eine:

Delphi-Quellcode:
TParallel.For (lowerBound, upperBound, Method);

Theoretisch und ginge das (fast so) auch mit Delphi 7, nur ohne anonyme Methoden. Und vielleicht nicht ganz so optimal.

Sir Rufo 2. Sep 2014 16:12

AW: XE 7 - Parallel Programming Library
 
Also im Code ist das doch sehr schön zu sehen
Delphi-Quellcode:
    if FParallel then
    begin

      // parallele Verarbeitung
      TParallel.For(Low(FOriginalBoard), High(FOriginalBoard),
        procedure (Value: Integer)
        begin
          ProcessCells(nil, Value);
        end);

    end else

      // sequentielle Verarbeitung
      for I := Low(FOriginalBoard) to High(FOriginalBoard) do
        ProcessCells(nil, I);

mkinzler 2. Sep 2014 16:16

AW: XE 7 - Parallel Programming Library
 
Zitat:

Gibts dann eigentlich auch ein "await" ?
Nicht Out-Of-The-Box aber leicht implementierbar:
Zitat:

Zitat von Chris Rolliston [url
http://delphifoundations.com/author/[/url] ]
Delphi-Quellcode:
type
  TTaskHelper = class helper for TTask
    class function Run<T>(const Sender: TObject; const Func: TFunc<T>;
      const CallOnReturn: TProc<TObject, T>): ITask; overload; static;
  end;
 
class function TTaskHelper.Run<T>(const Sender: TObject; const Func: TFunc<T>;
  const CallOnReturn: TProc<TObject, T>): ITask;
begin
  Result := Run(
    procedure
    var
      Value: T;
    begin
      Value := Func();
      TThread.Synchronize(nil,
        procedure
        begin
          CallOnReturn(Sender, Value);
        end);
    end);
end;
 
procedure TFormMain.Button1Click(Sender: TObject);
begin
  TTask.Run<string>(Self, LongTimeComing, FeedbackFromThread);
end;

http://docwiki.embarcadero.com/Libra...stem.Threading

mquadrat 2. Sep 2014 18:19

AW: XE 7 - Parallel Programming Library
 
mhh das muss ich mir mal morgens anschauen, wenn das Hirn noch nicht im Ruhemodus ist. Meine Lösung sieht so ganz anders aus :-)

EDIT: mhh ein wirklich await ist das aber nicht, oder?

Stevie 2. Sep 2014 18:41

AW: XE 7 - Parallel Programming Library
 
Zitat:

Zitat von mquadrat (Beitrag 1270743)
mhh das muss ich mir mal morgens anschauen, wenn das Hirn noch nicht im Ruhemodus ist. Meine Lösung sieht so ganz anders aus :-)

EDIT: mhh ein wirklich await ist das aber nicht, oder?

Nö isses nich. Das ist ne asynchrone Aktion mit einer in den Hauptthread synchronisierten Aktion im Abschluss.
Async/await für Delphi hab ich hier mal gebastelt. Für XE7 kann ich das auch einfach umstellen, dass System.Threading dafür als Backend hergenommen wird.

mquadrat 3. Sep 2014 12:44

AW: XE 7 - Parallel Programming Library
 
Kommt halt drauf an, was deine Tasks noch so können. Hatte mir bei DSharp damals nur das DataBinding angeschaut.

Stevie 3. Sep 2014 13:36

AW: XE 7 - Parallel Programming Library
 
Zitat:

Zitat von mquadrat (Beitrag 1270872)
Kommt halt drauf an, was deine Tasks noch so können. Hatte mir bei DSharp damals nur das DataBinding angeschaut.

Die können nicht viel, ist nur nen kleiner Wrapper um nen TThread, ohne Threadpooling und den ganzen Zauber :)

Sir Rufo 3. Sep 2014 13:54

AW: XE 7 - Parallel Programming Library
 
Nur mal so zum Spass so ein einfaches Parallel
Delphi-Quellcode:
unit Parallel;

interface

uses
  System.SysUtils;

type
  TParallel = class
    class procedure Execute( ALow, AHigh : Int64; AProc : TProc<Int64> );
  end;

implementation

uses
  System.Generics.Collections,
  System.SyncObjs,
  System.Classes;

{ TParallel }

class procedure TParallel.Execute( ALow, AHigh : Int64; AProc : TProc<Int64> );
  procedure BuildThread( AEvent : TEvent; AValue : Int64 );
  var
    LThread : TThread;
  begin
    // Event zurücksetzen
    AEvent.ResetEvent;
    // Anonymen Thread erzeugen
    LThread := TThread.CreateAnonymousThread(
        procedure
      begin
        // Arbeit ausführen
        AProc( AValue );
        // Event setzen
        AEvent.SetEvent;
      end );
    // Thread starten
    LThread.Start;
  end;

var
  LMaxThreads : Integer;
  LThread : TThread;
  LIdx : Integer;
  LEvents : TList<TEvent>;
  LEventArray : THandleObjectArray;
  LSignaled : THandleObject;
  LEvent : TEvent;
  LIter : Int64;
begin

  // Events vorbereiten

  LMaxThreads := TThread.ProcessorCount;

  LEvents := TObjectList<TEvent>.Create( True );
  LEvents.Capacity := LMaxThreads;

  SetLength( LEventArray, LMaxThreads );
  for LIdx := low( LEventArray ) to high( LEventArray ) do
    begin
      LEvent := TEvent.Create( nil, True, True, '' );
      LEvents.Add( LEvent );
      LEventArray[LIdx] := LEvent;
    end;

  // Jetzt wird es parallel

  LIter := ALow;

  while LIter <= AHigh do
    begin
      // Warten, bis EIN Event wieder frei ist
      TEvent.WaitForMultiple( LEventArray, INFINITE, False, LSignaled );
      BuildThread( LSignaled as TEvent, LIter );
      Inc( LIter );
    end;
  // Warten, bis ALLE Events wieder frei sind
  TEvent.WaitForMultiple( LEventArray, INFINITE, True, LSignaled );
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:18 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