Einzelnen Beitrag anzeigen

treepwood

Registriert seit: 26. Mai 2008
5 Beiträge
 
#1

Problem mit 2 Threads und CPU-Auslastung

  Alt 26. Mai 2008, 22:42
Hallo,
ich habe ein seltsames Problem:
Es werden 2 Threads gestartet, die die CPU für eine bestimmte Zeit vollständig beanspruchen.
Jeder Thread wird einem Kern zugewiesen (was im Grunde egal ist).
Auf einem Core2 sollte jetzt die CPU-Last 100% betragen.

Prozedur "haenge" bleibt 10 Sekunden in einer Schleife und führt Stringoperationen durch
Im "Button6Click" wird das ganze aktiviert.

* Wenn beide Zeilen (Kommentar "Thread-Bremse") auskommentiert sind, ist die CPU-Last 100% (also 2 Kerne)
(so wie erwartet; 50% pro Thread)

* Wenn eine der Problem-Zeilen(Thread-Bremse) aktiv ist, fällt die Last auf unter 30%
(das war nicht erwartet, zumindest nicht von mir )

* Zwinge ich das Programm, nur eine CPU zu verwenden, ist die CPU-LAST 50% (nur ein Kern)
aber MIT der aktiven Zeile (Kommentar "Thred-Bremse")

* Zusammengefaßt: 2 Threads auf 2 CPUs sind langsamer als 2 Threads auf einer!
-> siehe Anzahl Durchläufe im Quelltext-Kommentar

* Ich habe festgestellt, daß die besagten Zeilen extrem hohe Kontext-Switches verursachen;
Vielleicht hängt das mit dem Speichermanagement von SetLength zusammen ?
ShortString oder HugeString führen zum gleichen Ergebnis

* Delphi 6; auf Core2 E6300


Vielleicht hat jemand eine Idee.
Vielen Dank im Voraus!


Jetzt zum Code:

Delphi-Quellcode:
procedure haenge;
var l, x:longint; s :shortstring; cnt :int64;
begin
  // Str. erzeugen für pos, wenn Setlength auskommentiert
  s:=''; for x:= 0 to 200 do s:= s + chr(x);

  cnt:= 0; // durchlaufzähler
  L:=gettickcount+10000;
  while gettickcount<l do begin

    // ---> ohne folgende zwei Zeilen: 111 Mio Durchläufe pro CPU-Kern, CPU-Auslastung 100%
    // ---> MIT Setlength: 0.4 Mio um 25%
    // * Es ist fast egal ob beide Zeilen, oder nur eine der Zeilen aktiv sind
    // * Procedure "haenge" mit anderem Namen nochmal erstllen und beide getrennt
    // aufrufen ändert auch nichts
    // * Processexplorer zeigt extrem hohes Kontextswitching an
    setlength(s, 200+ random(50) ); // Thread-Bremse 1 auf core2
    s[0]:= char( 200+ random(50) ); // Thread-Bremse 2 auf core2


    // irgendwelche Aktionen...
    s:= copy(s, 1+ random(10), 50 + random(10) );
    x:= pos('*', s);
    s:= trim(s);
    inc(cnt);
  end;

  messagebox(0, pchar('Durchläufe: '+ inttostr(cnt)), '', 0);
end;


procedure TForm1.Button6Click(Sender: TObject);
var nix,id:integer; p1,p2 :ThreadParameter; ok :boolean;
       mask_alt, mask_p, mask_s :dword; hthr :THandle;
begin
  id:= BeginThread(nil, 0, @haenge, nil, 0, hthr);
  mask_alt:= SetThreadAffinityMask( id, 1 );

  id:= BeginThread(nil, 0, @haenge, nil, 0, hthr);
  mask_alt:= SetThreadAffinityMask( id, 2 );
end;
  Mit Zitat antworten Zitat