AGB  ·  Datenschutz  ·  Impressum  







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

programm mit thread langsamer als ohne

Offene Frage von "jaenicke"
Ein Thema von canonmclay · begonnen am 7. Jun 2011 · letzter Beitrag vom 10. Jun 2011
Antwort Antwort
Seite 1 von 3  1 23      
canonmclay

Registriert seit: 7. Jun 2011
12 Beiträge
 
#1

programm mit thread langsamer als ohne

  Alt 7. Jun 2011, 01:48
Hi ihr,

wir haben in der schule als letzes Thema in Info ein Projekt zum Verteilten Rechnen gestartet und abgeschlossen. Da ich aber jetzt abi hab und mich geistig fit halten wollte, habe ich mich ein wenig in Threads eingearbeitet. Unser Programm funktioniert so, das ein Server an mehrere Rechner im Netzwerk auf denen ein Client Progri läuft einen md5-hash schickt, welcher vom Client dann Per Brute Force versucht wird zu lösen. Dabei rechnet ein Client immer ein bestimmtes Paket aus, welches vom Server vorgegeben wird. (Wie genau wir das gemacht haben erspare ich euch mal, hat ja nix mit dem Problem zu tun).

Nun mein Problem:
Üblicherweise dauert das Rechnen eines Paketes auf meinem Rechner ca 7 sek. Wenn ich jedoch die Rechen routine in einem gesonderten Thread auslagere, so dauert die Rechenzeit für ein Paket fast 20 sek. Weiß jemand woran das liegen könnte? (Sinn des ganzen ist, das ein Client auf einer Dual Core maschine 2 Pakete Gleichzeitig Rechnen soll. Das Problem des Verteilens auf einzelne Cores habe ich bereits gelöst.)
Achja: ein "Rechen-Paket" besteht aus 857.375 versch. Hashes die gebildet und mit dem zu knackenden verglichen werden. (hab i-wo gelesen, das bei "einfachen" Operationen (addition ect.) das mit threads immer länger dauert...)

Ich kann auch gerne den Code hochladen, wenn dies erforderlich ist .

Gruß
McLay
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: programm mit thread langsamer als ohne

  Alt 7. Jun 2011, 01:56
Eventuell wäre es auch gut, wenn du mal etwas Code zeigst, denn ohne kann keiner (von uns) sagen, wo du den Fehler bverbaut hast oder ob es einfach so ist und es unabdingbar langsamer werden mußte.

Ja, man kann duch Multithreading etwas langsamer machen.
> zusätzliche Synchronisation zwischen den Threads
> zu exzessives Synchronize mit dem Hauptthread
> mechanische Bremsen > wenn z.B. zwei gleichzeitig auf die Festplatte zugreifen, dann bremsen sie sich aus, da der Schreib-/Lesekopf viel Zeit verbraucht, um ständig zwischen den einzelnen Zugriffen hin- und herzuspringen.
> uvm.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#3

AW: programm mit thread langsamer als ohne

  Alt 7. Jun 2011, 01:58
Herzlich Willkommen in der DP.

Es kommt immer darauf an, wie du die Programmierung bei Threads vornimmst. Verwendest du viele Synchronisations-Methoden können sich Threads durchaus ausbremsen oder unter Umständen zu einem Deadlock führen. Ohne dir aber unterstellen zu wollen, dass das so der Fall ist, wäre ein minimales Beispiel, zur Not aber auch der ganze, notwendige Code, sinnvoll

-- EDIT: Wo war dieses mal der rote Kasten!? :grml:

-- EDIT2: Ich mag himitsus Liste auch noch eine ThreadedList hinzufügen, da das eine Bremse sein kann, die ich letzter Zeit häufiger gesehen habe.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
canonmclay

Registriert seit: 7. Jun 2011
12 Beiträge
 
#4

AW: programm mit thread langsamer als ohne

  Alt 7. Jun 2011, 13:53
So hier mal die Thread-Teile des Progamms:

Delphi-Quellcode:

type
  strx = string[40];

  knack = class(TThread)
  private
    nachicht:string;
    g:BOOLEAN;
    pw : STRING;
    flabel4,flabel5:Tlabel;
    suchwort:strx;
    ersterbuchstabe:string;

    fwort:Tedit;

    fcheck: TCheckBox;

    procedure DoVisualSwap1;
    procedure dovisualswap2;
    function knacke(temptext:STRING):STRING;
    { Private declarations }

  protected
     procedure Execute; override;
  public
    constructor create(anzeige1,anzeige2:Tlabel;wort:Tedit;servernachicht:STRING;check: TCheckBox);


  end;

procedure knack.DoVisualSwap1; // anzeigen des gesendeten Buchstabens
BEGIN
  flabel4.caption:='Hash:' +suchwort;
  flabel5.caption:='Vorgegebene(s) Zeichen: "'+ersterbuchstabe+'"';
END;


procedure knack.dovisualswap2; //Hier wird das gefundene PW übergeben
BEGIN
  fwort.text:=PW;
  fcheck.checked:= g;
END;


function knack.knacke(temptext:STRING):STRING;

VAR k,i,j:integer;
    abc:STRING;

BEGIN

   g:=false; //inititalisieren der Variablen

   suchwort:='';
   ersterbuchstabe:='';
   k:=0;

   ///Die empfangene Nachricht wird in Hash und Buchstaben zerlegt.
   ///suchwort = Hash vom Server
   ///k = anzahl der Buchstaben die der Server vorgibt
   for i := 1 to 36 do
     begin
      if (i<=33) and (i>1) then suchwort:=suchwort+temptext[i];
      if i=35 then k:=strtoint(temptext[35]);
     end;

   for j := 1 to k do
     begin
      ersterbuchstabe:=ersterbuchstabe+(temptext[35+j]);
      ///Die ersten vorgegebenen Buchstaben werden angegeben.
     end;

   synchronize(dovisualswap1);

   abc:=' ';//Das sind die ERSTEN Acsii-Zeichen (3x leer) mit denen begonnen wird

   while length(abc)<4 do
     begin
       if suchwort=MD5Print(MD5String(ersterbuchstabe+abc)) then
         begin
           g:=true;
           result:=abc;
           break;
         end; // if suchwort

       abc:=strhoeher(abc);
     end; // while

////^^^^Hier drüber wird abc immer eins nach oben gesetzt und davon der Hash gebildet.
////^^^^Wenn der Hash = dem gesendetem Hash dann abbrechen und dem Server das PW melden.

END;

constructor knack.create(anzeige1,anzeige2:Tlabel;wort:Tedit;servernachicht:STRING;check: TCheckBox);
BEGIN
 flabel4:=anzeige1;
 flabel5:=anzeige2;

 fcheck:=check;
 fwort:=wort;
 nachicht:=servernachicht;

 freeOnTerminate := True;
 inherited Create(False);
 Priority := tpHighest;
 SetThreadAffinityMaskByID(getcurrentthreadid,1);


END;


procedure knack.Execute;
VAR tmp : STRING;
    i,k:INTEGER;
begin

  pw:='';

  tmp:=knacke(nachicht); //bearbeiten eines Rechenpaketes

  IF g THEN //Wenn PW gefunden, dann wird das Passwort in die Variable PW gespeichert
    BEGIN
      k:=strtoint(nachicht[35]);
      FOR i:=1 TO k DO PW:=pw+nachicht[i+35];
      PW:=pw+tmp;

      synchronize(dovisualswap2); //Hier wird dann das PW übergeben
    END;



  { Place thread code here }
end;

es gibt auf noch eine thread done Procedure, aber ich denk die is eher nebensächlich:

Delphi-Quellcode:
procedure tform1.ThreadDone(Sender: TObject); // beim fertigstellen des Threads wird hier ggf. ein neuer gestartet
BEGIN // Oder das gefundene PW übermittelt
  IF (checkbox1.checked AND clients.Active)
     THEN
       clients.Socket.SendText('| Das Passwort ist '+ edit3.text +' |')
     ELSE
     BEGIN
       //dec(anzahlthreads);
       clients.Socket.SendText('ich warte'); //anfordern des neues Paketes
     END;

END;

also an synchros hab ich halt nur eine am anfang und eine am ende des Threads. Des weiteren läuft das Programm erstmal nur mit einem Thread, also ohne Paralleles arbeiten, wie das Standartprogramm.
Mechanische Bremsen sind keine Vorhanden, da kein Festplattenzugriff erforderlich ist.

Ich lad mal ne Server Version, den normalen Client und den Thread Client komplett hoch, falls der Code oben nicht reicht, oder wer dran interessiert ist^^.

vielen dank für die schnelle Hilfe

Gruß McLay
Angehängte Dateien
Dateityp: rar Client + Server.rar (771,2 KB, 13x aufgerufen)
  Mit Zitat antworten Zitat
canonmclay

Registriert seit: 7. Jun 2011
12 Beiträge
 
#5

AW: programm mit thread langsamer als ohne

  Alt 8. Jun 2011, 00:56
keiner mehr ne idee :S
  Mit Zitat antworten Zitat
Benutzerbild von ULIK
ULIK

Registriert seit: 25. Sep 2006
Ort: Regensburg
427 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: programm mit thread langsamer als ohne

  Alt 8. Jun 2011, 06:05
Probiers halt mal aus, ob's an dem Synchronize liegt: Zeilen auskommentieren und dann messen.
Ansonsten: Probiers erst mal ohne Thread-Priority Spielereien und spendier dem Code am Beginn und am Ende der Execute Methode mal etwas Code zur Zeitmessung (GetTickCount)
Generell: nicht vermuten wo es langsam ist, sondern messen!

Grüße,
Uli
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.589 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: programm mit thread langsamer als ohne

  Alt 8. Jun 2011, 06:08
Naja, was du machst ist ja explizit nicht mehrere Threads parallel laufen zu lassen, sondern nach dem Ende eines Threads den nächsten Datensatz anzufordern.

Du rechnest also weiter hintereinander, nicht parallel, nur dass die Threadsynchronisierung dazukommt. Das kann nur länger dauern.

Zudem blitzen die Threads nur kurz auf, die sind bei mir in dem Beispielprogramm nach vielleicht einer Sekunde jeweils fertig. Das macht auch nicht ganz so viel Sinn.

Besser wäre, wenn du gleich mehrere Aufträge verteilst, damit der Thread auch ein bisschen was zu tun hat und außerdem auch mehrere Threads parallel laufen lässt. Stichwort Threadpool zum Beispiel.
Außerdem solltest du die Zuweisung an einen bestimmten Kern weglassen. Windows verteilt das in der Regel schon am besten alleine.

@ULIK:
Wozu ins Blaue daneben raten, wenn du im Quelltext doch schnell sehen kannst, dass erst in ThreadDone der nächste Datensatz angefordert wird usw.?
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!

Geändert von jaenicke ( 8. Jun 2011 um 06:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von ULIK
ULIK

Registriert seit: 25. Sep 2006
Ort: Regensburg
427 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: programm mit thread langsamer als ohne

  Alt 8. Jun 2011, 07:49
@ULIK:
Wozu ins Blaue daneben raten, wenn du im Quelltext doch schnell sehen kannst, dass erst in ThreadDone der nächste Datensatz angefordert wird usw.?
Indem ich mir den Quellcode nur schnell am Morgen angeschaut hab?
Mir ging's eigentlich hauptsächlich darum, daß man bei Performanceproblemen halt erst mal messen sollte und wenn der TE schon die Synchronisation erwähnt, dann halt mal ausprobieren und schauen, ob es das ist.

Grüße,
Uli
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#9

AW: programm mit thread langsamer als ohne

  Alt 8. Jun 2011, 11:17
SetThreadAffinityMaskByID(getcurrentthreadid,1);
Dir ist schon klar, daß das Create im Kontext des Hauptthreads aufgerufen wird? Der obige Befehl wirkt sich somit lediglich auf den Hauptthread aus und nicht auf den des gerade erzeugten TThread-Objekts.

Du kannst aber auch mal testen, wie das Verhalten ist, wenn du die beiden Synchronize-Aufrufe auskommentierst. Damit könnte man eventuell die Thread-Synchronisation als Bremse ausschließen.

Nebenbei wichtig: welche Delphi-Version nimmst du?
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
canonmclay

Registriert seit: 7. Jun 2011
12 Beiträge
 
#10

AW: programm mit thread langsamer als ohne

  Alt 8. Jun 2011, 15:22
SetThreadAffinityMaskByID(getcurrentthreadid,1);
Dir ist schon klar, daß das Create im Kontext des Hauptthreads aufgerufen wird? Der obige Befehl wirkt sich somit lediglich auf den Hauptthread aus und nicht auf den des gerade erzeugten TThread-Objekts.

Du kannst aber auch mal testen, wie das Verhalten ist, wenn du die beiden Synchronize-Aufrufe auskommentierst. Damit könnte man eventuell die Thread-Synchronisation als Bremse ausschließen.

Nebenbei wichtig: welche Delphi-Version nimmst du?

>achso ich dachte man musst das im create nutzen... naja ich habs mal weggemacht
>auch das ausklammern der synchros hat keinen effekt auf die geschwindigkeit
>ich gurke auf einer version 6 rum...


Naja, was du machst ist ja explizit nicht mehrere Threads parallel laufen zu lassen, sondern nach dem Ende eines Threads den nächsten Datensatz anzufordern.

Du rechnest also weiter hintereinander, nicht parallel, nur dass die Threadsynchronisierung dazukommt. Das kann nur länger dauern.

Zudem blitzen die Threads nur kurz auf, die sind bei mir in dem Beispielprogramm nach vielleicht einer Sekunde jeweils fertig. Das macht auch nicht ganz so viel Sinn.

Besser wäre, wenn du gleich mehrere Aufträge verteilst, damit der Thread auch ein bisschen was zu tun hat und außerdem auch mehrere Threads parallel laufen lässt. Stichwort Threadpool zum Beispiel.
Außerdem solltest du die Zuweisung an einen bestimmten Kern weglassen. Windows verteilt das in der Regel schon am besten alleine.
> naja ich wär erstmal froh, wenn das mit einem Thread vernünftig läuft, daher lasse ich bisher nur einen laufen
> ich möchte ja, das erst nachdem ein Paket bearbeitet wurde, der Server kontaktiert wird, und ein neues Paket angefordert wird, demnach muss ich warten bis der thread fertig ist. Außerdem, macht eine threadsynchronisierung einen unterschied von fast 14 sek aus?
>Zu deinem PC: was für eine CPU hast du 0o. Im normalen Programm schaff ich ein Paket in ca. 7sek, mit einem Thread ca. 20 sek. (Dual - Core E6300 mit 1,86GHz, bei nem Kumpel 2,8GHz ca. 4 und 12 sek.). Von daher wenn ich die Pakete größer mache, dann muss ich ja 81.450.625 Schleifendurchgänge Rechnen, anstatt ca. 800.000 ... das dauert dann viel zu lange...
  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 22:37 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