Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   THreads in ein Array schreiben (https://www.delphipraxis.net/167303-threads-ein-array-schreiben.html)

bernhard_LA 22. Mär 2012 22:36

THreads in ein Array schreiben
 
ich benötige für meine Anwendung ein Array of integer of integer . Dieses Array möchte ich gleichzeitig durch mehrere Threads beschreiben, ich bin auf der Suche nach DEMO Code zu diesem Problem.
Kann jemand weitzerhelfen ?

Bummi 22. Mär 2012 22:55

AW: THreads in ein Array schreiben
 
Wenn das Array sich in den Dimensionen nicht ändert und die Threads beim schreiben nicht kollidieren können (z.B.)jeder Thread eine andere Zeile bearbeitet muss man gar nichts beachten.
Ansonsten würde ich über die Werte über eine Prozedur setzen bzw. Funktion lesen lassen die mit CriticalSections verriegelt ist ala
http://www.delphipraxis.net/167197-a...onisieren.html
http://www.delphipraxis.net/128266-t...erstellen.html

Furtbichler 23. Mär 2012 06:07

AW: THreads in ein Array schreiben
 
Wobei das Problem an sich ziemlich interessant ist, denn auch wenn eine Critical Section wenig Overhead erzeugt, kann man da vielleicht noch etwas drehen, aber eine Demo kann man nur erstellen, wenn man weiß, wie die Matrix genau beschrieben wird.

Kann man die Operation vielleicht so aufteilen, das keine CS benötigt wird? Mehr Threads als CPUs bringen bezüglich Performancegewinn nichts, also könnte man die Matrix in N (N=Anzahl Core) Abschnitte aufteilen, die gleichzeitig befüllt werden.

Sind die Berechnungen einer Zelle X,Y von dem Ergebnis anderer Zelle abhängig? Dann müsste zusätzlich ein Synchronisationsmechanismus her.

himitsu 23. Mär 2012 08:38

AW: THreads in ein Array schreiben
 
Man könnte auch mehrere CriticalSections verwenden, z.B. je Eine für die erste Array-Ebene,
falls die Threads nicht nur je auf ein Unterarray zugreifen.

SirThornberry 23. Mär 2012 16:34

AW: THreads in ein Array schreiben
 
Zitat:

Zitat von Bummi (Beitrag 1158057)
Wenn das Array sich in den Dimensionen nicht ändert und die Threads beim schreiben nicht kollidieren können (z.B.)jeder Thread eine andere Zeile bearbeitet muss man gar nichts beachten.

Doch, zumindest war das früher so. Wenn man ein Integer schreibt, dieser aber nicht genau am Speicher ausgerichtet ist wird der Speicher davor und/oder dahinter auch gelesen und geschrieben. Und wenn ein anderer Thread gerade im selben Bereich unterwegs ist kann das schon kollidieren

bernhard_LA 26. Mär 2012 17:21

AW: THreads in ein Array schreiben
 
im Ereignis Thread.Create(....) übergebe ich ein Array ancc vom Typ array or array of Real
Bei dem Aufruf von Thread.Execute; schreibt die letzte Anweisung in ein bestimmtetes Segment von ancc. Jeder Thread soll in ein bestimmtest Segment schreiben, die Segmente haben keine Überlappung.

Leider schreibt nur der erste THread seine Daten richtig in mein Array ancc , die anderen Threads scheinen überhaupt nichts am Feld zu verändern



Delphi-Quellcode:

  TFASTNCCThread = class(TThread)
  private
  FSearchArea : TRect;
  Ftemplatefct : T2Dfct;
  Ffeaturefct : T2Dfct;
  FnccGlobal : T2Dfct;
  FNCCLocal : T2Dfct;
  protected
  procedure Execute; override;
  public
  constructor create(atemplatefct, afeaturefct : T2Dfct; var ancc : T2Dfct ; aSearchArea: TRect );
  end;


constructor TFASTNCCThread.create( atemplatefct, afeaturefct : T2Dfct; var ancc : T2Dfct ; aSearchArea: TRect );
begin
     inherited Create(True);

     FSearchArea := aSearchArea;

     ftemplatefct := atemplatefct;

     ffeaturefct := afeaturefct;

     FnccGlobal:= ancc;

end;

procedure TFASTNCCThread.Execute;
begin
    NameThreadForDebugging('FASTNCCThread');
  { Thread-Code hier einfügen }
  try
       fastcrosscorrelation( ...... );
  except
   // on e : exception do
   //  begin
   //   do something in case of an error
   //  end;
   end;

   NCCCopyLocalArraytoGlobalArray(FnccLocal, FnccGlobal, fsearchArea ); //  write back results to ancc array

end;

Bummi 26. Mär 2012 17:32

AW: THreads in ein Array schreiben
 
was da : write back results to ancc array
passiert dürfte der interessante Teil sein ....
wenn Du direkt auf dem per var übergebenen Array arbeitest und die Offsetparameter passen sollte es laufen ...

bernhard_LA 27. Mär 2012 08:13

AW: THreads in ein Array schreiben
 
Stimmt, das schreiben in das Array ist nicht das Problem, allerdings die Rechenzeit, welche unverändert bleibt :(

Delphi-Quellcode:

     for i:= 0 to MaxThreads-1 do
       begin

       aFASTNCCThread:= TFASTNCCThread.Create ( ..... );

       aFastNCCThread.Execute;

       end;
egal wieviele Threads ich starte die Rechenzeit bleibt immer konstant

Bummi 27. Mär 2012 08:28

AW: THreads in ein Array schreiben
 
wieso rufst Du Execute auf? Start wäre im Threadkontext, oder create ohne suspended

bernhard_LA 27. Mär 2012 08:54

AW: THreads in ein Array schreiben
 
ich habe die Berechnung der jeweiligen Teilmatrix in die Routine Thread.execute gepackt.

Vom Verständnis müsste er doch Thread.Execute starten, aber nicht auf die Beendigung dieser Anweisung warten sondern
gleich den nächsten THREAD erzeugen und starten.... sehe ich etwa falsch ?

Bummi 27. Mär 2012 09:09

AW: THreads in ein Array schreiben
 
Auf die Art wird das Execute im Kontext des Hauptthreads ausgeführt, wie eine normale Prozedur.
Der Thread ruft nach dem starten intern Execute auf, ein Aufruf von außen macht keinen Sinn.

bernhard_LA 27. Mär 2012 14:31

AW: THreads in ein Array schreiben
 
Habe die Antwort nicht ganz verstanden :oops:

wenn ich die Zeile
Delphi-Quellcode:
tread.execute
auskommentiere, rechnet der Thread aber nicht mehr.



------
http://radstudiodemos.svn.sourceforg...i/RTL/Threads/

DeddyH 27. Mär 2012 14:33

AW: THreads in ein Array schreiben
 
Dann schreib doch im Konstruktor (des Threads) als letzte Zeile "Start;" hin.

flipdascript 27. Mär 2012 14:35

AW: THreads in ein Array schreiben
 
Falls Du den Thread suspended erstellt hast kannst Du ihn einfach mit Resume starten.
In dem Fall ersetze einfach
Delphi-Quellcode:
aFastNCCThread.Execute;
durch
Delphi-Quellcode:
aFastNCCThread.Resume;
.
Du kannst die Threads aber auch nicht suspended erstellen, dann rennen sie sofort nach ihrer Erstellung los.

bernhard_LA 27. Mär 2012 17:29

AW: THreads in ein Array schreiben
 
Liste der Anhänge anzeigen (Anzahl: 1)
mein Problem besteht darin, ich kann in meiner Schleife i Threads erzeugen
Delphi-Quellcode:
   for i:= 0 to Anzahl Threads do
       
         aThread := TMyThread.Create( Übergabe der Ausgangsmatrizen, Überhabe der Ergbnismatrix);

         aThread.Execute //  Berechne hier eine Teilmatrix und dann das Ergebnis in die große Matrix schreiben

      end;
, jeder erzeugte Thread berechnet auch eine TeilMatrix meines Problems, das Endergebnis ist richtig.
leider Ist die Zeit für die Berechnung der Matrizen ohne Threads genauso lange wie für die Berechnung der Matrizen mit 8 Threads auf einem System mit 4 Cores. Meine Erwartung :
T _Threads ~ T_Ohne_Threads / Anzahl_der_Threads.
Ich frage mich halt ob der Code auf die Abarbeitung von thread.execute wartet, die Parallelberechnung klappt irgendwie nicht

DeddyH 27. Mär 2012 18:07

AW: THreads in ein Array schreiben
 
Wäre es nicht bequemer, auf etwas Fertiges wie z.B. Andreas' AsyncCalls oder die OmniThreadLibrabry zurückzugreifen?

Iwo Asnet 27. Mär 2012 18:20

AW: THreads in ein Array schreiben
 
So geht das!
Delphi-Quellcode:
   for i:= 0 to Anzahl Threads do
     TMyThread.Create( Übergabe der Ausgangsmatrizen, Überhabe der Ergbnismatrix);
...
...
Constructior TMyThread.Create (...params);
Begin
  inherited Create(False);
  FreeOnTerminate := True;
  ... initialize your Ausgangsmatrizen and stuff
  Resume; // Nicht nötig, aber lesbar
End;

himitsu 27. Mär 2012 18:46

AW: THreads in ein Array schreiben
 
Zitat:

Zitat von bernhard_LA (Beitrag 1158957)
mein Problem besteht darin, ich kann in meiner Schleife i Threads erzeugen
Delphi-Quellcode:
   for i:= 0 to Anzahl Threads do
       
         aThread := TMyThread.Create( Übergabe der Ausgangsmatrizen, Überhabe der Ergbnismatrix);

         aThread.Execute //  Berechne hier eine Teilmatrix und dann das Ergebnis in die große Matrix schreiben

      end;

Nein, dein Problem ist, daß du nicht lesen kannnt.

Dir wurde mehrmals gesagt, daß man Execute nicht aufruft. (wird auch in jedem Thread-Tutorial erklärt)
PS: Execute ist mit Absicht als Protected deklariert, damit sollte eigentlich klar werden, daß man dieses nicht von extern aufruft.

Wobei ich die Möglichkeiten der Generics und anonymen Methoden sehr zu schätzen lernte.
Delphi-Quellcode:
TThread.CreateAnonymousThread(procedure
  begin
    ...
    // läuft in einem Thread
    ...
    TThread.Synchronize(nil, procedure
      begin
        ...
        // läuft im Hautthread/VCL-Thread
        ...
      end);
    ...
    // läuft in einem Thread
    ...
    TThread.Synchronize(nil, procedure
      var
        i: Integer;
      begin
        ...
        // läuft im Hautthread/VCL-Thread
        for i := 0 to ...
        ...
      end);
    ...
    // läuft in einem Thread
    ...
  end).Start;

bernhard_LA 27. Mär 2012 19:49

AW: THreads in ein Array schreiben
 
meine Leitung ist wohl ziemlich lang ... :(

aber : bin beim Design der Klasse nach http://wiki.delphigl.com/index.php/T...Multithreading vorgegangenm dort ist ja auch in Thread.execute der Code für die Berechnung eingetragen


Habe mal den ganzen Code aus der Procedure Execute bereits in die Procedure Create verschoben und rufe dann Thread.execute in der Schleife nicht mehr auf. Das Endergebnis ist wieder richtig, nur sehr ich keinen Geschwindigkeitsgewinn

himitsu 27. Mär 2012 19:56

AW: THreads in ein Array schreiben
 
Nochmal für Langsame.

In Create kommt alles, was außerhalb des Threads initialisiert wird.
In Excecute kommt der Code, welcher im Thread ausgeführt werden soll.
Und hast du dort (siehe deine verlinkte Seite) irgendwo gesehn, daß irgendwer die Methode Execute aufruft? Nein!

Im Create (wenn nicht Suspended) wird der Thread gestartet.
Wenn Suspended, dann wird beim Delphi-Referenz durchsuchenTThread.Resume Delphi-Referenz durchsuchenTThread.Start der Thread gestartet.
Wenn der Thread anläuft, dann ruft dieser das Execute auf und führt es in seinem Kontext aus.

Zitat:

bin beim Design der Klasse nach ...
Nicht nur beim Design der Klasse danach vorgehn, sondern auch danach, wie die Klasse dort verwendet wird.

bernhard_LA 27. Mär 2012 20:40

AW: THreads in ein Array schreiben
 
OK, gestehe das Manual nur halb gelesen zu haben ... man soll also

Delphi-Quellcode:
      Thread.Create(....)
      Thread.Start;
anstelle meiner Lösung

Delphi-Quellcode:
      THread.Create(...)
      Threat.Execute;
Aktuell habe ich zwei Probleme :
a) mit der ersten Lösung rennt mein Programm in < 1 Sekunde durch .... nur kommt kein Array zurück
thread.start ruft thread.execute auf, die Reiehnfolge der Berechnung der Teilmatrizen ist jetzt anders
als wenn execute verwenden....

b) mit meiner Lösung kommt zwar das Richtige Array zurück , aber ohne der Geschwindigkeitsvorteil

meine Lösung mit 2 Threads ~ 15 sec
meine Lösung mit 4 Threads ~ 15 sec
meine Lösung mit 8 Threads ~ 16 sec
meine Lösung mit 8 Threads ~ 17 sec
meine Lösung mit 32 Threads ~ 18 sec
meine Lösung OHNE Threads ~ 16 sec

Klaus01 27. Mär 2012 21:13

AW: THreads in ein Array schreiben
 
Guten Abend,

werden in der execute Routine die Offset Parameter verändert?
Wenn ja, dürfte das ein Problem sein, da ja nun die Thread "parallel" laufen.

Grüße
Klaus

bernhard_LA 27. Mär 2012 22:00

AW: THreads in ein Array schreiben
 
schwierige Geburt für paralleles Schreiben in ein Array :



fehler gefunden !!!!!

Array als Zeiger übergeben und wieder abholen .... dann gehts !!!!

bernhard_LA 29. Mär 2012 08:13

AW: THreads in ein Array schreiben
 
**** Für die Nachwelt ****

DER CODE SPIELT && PERFORMNCE WIE ERWARTET !!!!!!!

vielen Dank für die Inputs zu diesem Thema, ich konnte nur teilweise mit den Posts hier wenig anfange weil sobald ich den Vorschlägen gefogt bin mein Code weniger gespielt hat.

Bei Thread.Create (....) ; Thread.execute kamen ja schon die richtigen Ergebnisse , Bei Thread.Create(....) Threat. Start kamen keine Ergebnisse.

Die Lösung zum Problem besteht auf 3 Themen

a) Bei Thread.Create( var AnyValue ) übergeben und hoffen ich bekomme Änderungen in AnyValue auch in anderen Threads mit geht nicht, ich muss in der CREATE procedure einen Zeige auf AnyValue setzten , dann reden wir in allen Threads über die selbe Variable AnyValue

b) Änderungen in Threat.Execute an AnyValue habe ich über eine Criticalsection beschränkt


c) bei Thread.Create übergebe ich jetzt noch einen INT-Pointer RunningThreads der in EXECUTE zum Schluss noch heruntergezählt wird. Weitermachen im Gesamten Code darf ich erst wenn alle THread fertig sind, ggf. auch beachten


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