AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Multithreading

Ein Thema von Gruber_Hans_12345 · begonnen am 24. Jul 2023 · letzter Beitrag vom 25. Jul 2023
Antwort Antwort
Seite 1 von 3  1 23      
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.439 Beiträge
 
Delphi 2007 Professional
 
#1

Multithreading

  Alt 24. Jul 2023, 13:35
Hallo kann mal wer einen Blick auf meinen Code werfen - irgendwo habe ich da einen Denkfehler.

Das ist meine Threadklasse
Delphi-Quellcode:
type
    TTestThread = class(TThread)
    protected
        fWaitFinish : THandle;
        fResumeEvent : THandle;
        procedure Execute; override;
    public
        constructor Create();
        destructor Destroy; override;
    end;

destructor TTestThread.Destroy;
begin
    CloseHandle(fWaitFinish);
    CloseHandle(fResumeEvent);
    inherited;
end;

constructor TTestThread.Create();
var
    i : integer;
begin
    fResumeEvent := 0;
    fWaitFinish := CreateEvent(nil, TRUE, FALSE, nil);
    FreeOnTerminate := FALSE;
    inherited Create(TRUE);
end;

procedure TTestThread.Execute;

    procedure internalExecute;
    var
        i : integer;
        x : Byte;
    begin
        x := 9;
        for i:=1 to 10000000 do begin
            x := x xor (Random(9999999) mod 255);
        end;
        SetEvent(fWaitFinish);
    end;

begin
    fResumeEvent := CreateEvent(nil, TRUE, FALSE, nil);
    repeat
        internalExecute;
        if Terminated then break;
        WaitForSingleObject(fResumeEvent, INFINITE);
        ResetEvent(fResumeEvent);
    until Terminated;
    SetEvent(fWaitFinish);
end;
Und so rufe ich das mit einer Art Threadpool auf

Delphi-Quellcode:
procedure TfrMDIChild.Button19Click(Sender: TObject);
var
    maxThreads : integer;
    tempFunc : TInterpreterFunDesc;
    hArrWait : array of THandle;
    threadList : array of TTestThread;

    function GetIdleThread : integer;
    var
        i : integer;
    begin
        for i:=0 to maxThreads-1 do
            if hArrWait[i] = 0 then begin
                threadList[i] := TTestThread.Create();
                hArrWait[i] := threadList[i].fWaitFinish;
                Result := i;
                exit;
            end;
        repeat
            Result := WaitForMultipleObjects(length(hArrWait), @hArrWait[0], FALSE, INFINITE);
        until (Result >= 0) and (Result < maxThreads);
        Result := Result - WAIT_OBJECT_0;
    end;

    procedure InitThreads;
    var
        i : integer;
    begin
        setlength(threadList, maxThreads);
        setlength(hArrWait, maxThreads);
        for i:=0 to maxThreads-1 do
            hArrWait[i] := 0;
    end;
    
var
    i : integer;
    threadIdx : integer;
    perfFreq : int64;
    perfStart : int64;
    perfEnd : int64;
begin
    QueryPerformanceFrequency(perfFreq);

    QueryPerformanceCounter(perfStart);
    maxThreads := TButton(Sender).Tag;
    InitThreads;
    for i:=0 to 100 do begin
        threadIdx := GetIdleThread;
        if threadList[threadIdx].fResumeEvent = 0 then begin
            threadList[threadIdx].Resume;
        end
        else begin
            ResetEvent(threadList[threadIdx].fWaitFinish);
            SetEvent(threadList[threadIdx].fResumeEvent);
        end;
    end;
    QueryPerformanceCounter(perfEnd);

    setlength(threadList, 0);
    setlength(hArrWait, 0);
    QueryPerformanceCounter(perfEnd);
    Memo1.Lines.Add('Threading ('+IntToStr(maxThreads)+' Threads : '+FormatFloat('0.00', (perfEnd-perfStart) * 1000 / perfFreq)+' ms');
end;
Den Testbutton rufe ich einmal mit einem Thread auf und einmal das er acht Threads machen soll
Das Ergebnis ist dann
Code:
Threading (1 Threads : 4446,57 ms
Threading (8 Threads : 5980,15 ms
Was übersehe ich da das er bei 8 gleichzeitigen Threads die Dauer so lange ist? (Die CPU Auslastung geht aber da schön auf fast 100% hoch)
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

AW: Multithreading

  Alt 24. Jul 2023, 14:55
Wie viele Kerne hat die CPU, auf der du das ausführst?
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.439 Beiträge
 
Delphi 2007 Professional
 
#3

AW: Multithreading

  Alt 24. Jul 2023, 14:58
Entwicklungsrechner ist ein virtualisierter mit 4 Kerne
Aber auch auf meinem Rechner hier dann direkt die EXE getestet und der hat 8 "echte" Kerne.
Bei beiden das gleiche - mit einem Thread ist es am schnellsten
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
fisipjm

Registriert seit: 28. Okt 2013
299 Beiträge
 
#4

AW: Multithreading

  Alt 24. Jul 2023, 14:59
Hey Hans,

wenn ich deinen Code beim Überfliegen richtig verstanden habe, erzeugst du doch im InternalExecute Teil immer die gleiche Aufgabe, für egal wie viele Threads. Spich jeder Thread hat die gleich Aufgabe und bei dem 8 Thread Pool kommt dann eben noch der Overhead drauf für das Threadhandeling.

Oder hab ich da was übersehen?


Edit: Code nicht verstanden

Geändert von fisipjm (25. Jul 2023 um 10:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#5

AW: Multithreading

  Alt 24. Jul 2023, 15:04
Wenn er 8 Kerne hat, dann musst du schon sicher stellen, das gar nix anderes läuft, damit er dieselbe Aufgabe 8mal durchführen kann auf 8 Threads, damit er genauso schnell ist, wie die Aufgabe 1mal auszuführen.
Ich habe das bei mit einem 12Kerner versucht bei mir (i7-12700, was nen 12-Kerner mit 8 P-Cores ist) und sehe in etwa die selbe Dauer mit einem oder mit acht Threads.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.439 Beiträge
 
Delphi 2007 Professional
 
#6

AW: Multithreading

  Alt 24. Jul 2023, 15:08
JA es soll im prinzip ienfahc 100 mal der code vom internalExecute ausgeführt werden - in dem Fall eine einfachste Version - die nichts anderes macht ausser primitive Berechnungen.

Daher sollte er mit 8 Threads ja meiner Meinung nach 8 mal so schnell sein wie mit einem Thread - okay ganzer Overhead und co aber zumindest 4 mal so schnell.

Und nicht wie in meinem Fall das es sogar langsamer ist diese 100 mal internalExecute auszuführen
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.623 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: Multithreading

  Alt 24. Jul 2023, 15:08
Was fisipjm schon schrieb: Solange Du die auszüführende Aufgabe nicht auf mehrere Threads verteilst sondern jeden Thread die komplette Aufgabe machen lässt, wird sich die Laufzeit nicht ändern. Im Gegenteil: Jeder zusätzliche Thread erhöht den Overhead.

Edit: Mist, gepennt. Man sollte nicht kommentieren, wenn man den Code nicht verstanden hat.
Thomas Mueller

Geändert von dummzeuch (24. Jul 2023 um 15:39 Uhr)
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.439 Beiträge
 
Delphi 2007 Professional
 
#8

AW: Multithreading

  Alt 24. Jul 2023, 15:10
Hmm verstehe ich nicht ganz

Ich möchte 100 mal die funktion internalExecute aufrufen

bei einem thread wird der eine Thread das 100 mal aufrufen

bei 8 Threads verteilt es sich, und im idealfall muss jeder Thread die funktion nur 12.5 mal aufrufen
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: Multithreading

  Alt 24. Jul 2023, 15:11
Mir war so, als sei der Zufallsgenerator je Thread unabhängig,
aber wenn es nur einen Globalen gäbe, dann wäre die Sache klar.

* in aufgerufenen Funktionen kann eine Synchronisierung drin sein
* und dann die Speicherzugriffe ... wenn alle Kerne auf den selben Speicher zugreifen, dann blocken viele CPUs hier auch gern
$2B or not $2B
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.439 Beiträge
 
Delphi 2007 Professional
 
#10

AW: Multithreading

  Alt 24. Jul 2023, 15:14
Mir war so, als sei der Zufallsgenerator je Thread unabhängig,
aber wenn es nur einen Globalen gäbe, dann wäre die Sache klar.

* in aufgerufenen Funktionen kann eine Synchronisierung drin sein
* und dann die Speicherzugriffe ... wenn alle Kerne auf den selben Speicher zugreifen, dann blocken viele CPUs hier auch gern
Danke das wars
Ohne Random verhält es sich nun wie ich es erwarte ...
Komisch im Source vom Randsom sieht man keine CriticalSections oder co


Aber nun kann ich weiter testen danke
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:02 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