Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi cpu zeit einer schleife auslesen (https://www.delphipraxis.net/115057-cpu-zeit-einer-schleife-auslesen.html)

Horst_ 5. Jun 2008 20:41

Re: cpu zeit einer schleife auslesen
 
Hallo,

etwas genauer, zählt Takte
Man kann auch CPUF bestimmen, aber bei Cool&quite und Konsorten etwas schwieriger..

Bei´m PentiumM
Startaufruf ~54 Takte
StoppAufruf ~56 Takte (Obwohl viel mehr gerechnet wird)
Delphi-Quellcode:
{APPTYPE Console}
uses
  sysutils;

const
  CPUF = 1700000;//CPU frequenz in khz

type
  tZeit = record
            t0, //letzter Start
            t1, //letzter Stopp
            dt, // Differenz Stopp-Start
            tsum, //Summe aller Differenzen
            StartStoppCnt : int64; //Anzahl Aufrufe
          end;
var
  tges,tdummy : tZeit;
  i : integer;
  j : int64;

procedure ZeitInit(var t:tZeit);
begin
  with t do
    begin
    t0:=0;
    t1:=0;
    dt:=0;
    tsum:=0;
    StartStoppCnt := 0;
    end;
end;

procedure ZeitStart(var t:tZeit);ASSEMBler;

asm
  // EAX ist der Zeiger auf t und muss gerettet werden
  // Weil der Compiler sonst durcheinander kommt
  MOV ECX,EAX
  rdtsc
  Xchg EAX,ECX
  mov Dword Ptr [t.t0], ecx
  mov Dword Ptr [t.t0+4], edx
end;

procedure ZeitStopp(var t:tZeit);Assembler;
asm
  // EAX ist der Zeiger auf t und muss gerettet werden
  // Weil der Compiler sonst durcheinander kommt
  MOV ECX,EAX
  rdtsc;
  Xchg EAX,ECX
  //Zeit in tStopp speichern
  mov Dword Ptr [t.t1], ecx
  mov Dword Ptr [t.t1+4], edx
  //dt bestimmen
  SUB ecx,Dword Ptr [t.t0]
  SBB edx,Dword Ptr [t.t0+4]
  mov Dword Ptr [t.dt], ecx
  mov Dword Ptr [t.dt+4], edx
  //tsum berechnen
  ADD ecx,Dword Ptr [t.tsum]
  ADC edx,Dword Ptr [t.tsum+4]
  MOV Dword Ptr [t.tsum],EcX
  MOV Dword Ptr [t.tsum+4],EDX
  //Cnt erhöhen Achtung nur 32 bit genutzt
  INC Dword Ptr [t.StartStoppCnt]
end;

begin
  ZeitInit(tGes);
  ZeitStart(tges);
   for i := 1 to 1000000 do
    j := sqr(i);
  ZeitStopp(tges);
  WriteLn(Format(' Gesamttakte %12d ',[tges.tsum]));
  WriteLn(Format(' Gesamtzeit  %12.6f ms',[tges.tsum/CPUf]));
  WriteLn(Format(' Gesamtzahl  %12d ',[tges.StartStoppCnt]));
  Writeln;

  //Wird länger dauern wegen des Overhead's
  //Bei mir 56 Takte pro Durchlauf
  ZeitInit(tGes);
  ZeitInit(tDummy);
  ZeitStart(tges);
  for i := 1 to 1000000 do
     begin
     ZeitStart(tDummy);
     end;
  ZeitStopp(tges);

  WriteLn(Format(' Gesamttakte %12d ',[tges.tsum]));
  WriteLn(Format(' Gesamtzeit  %12.6f ms',[tges.tsum/CPUf]));
  WriteLn(Format(' Gesamtzahl  %12d ',[tdummy.StartStoppCnt]));
  Writeln;

  //Bei mir 58 Takte pro Durchlauf
  ZeitInit(tGes);
  ZeitInit(tDummy);
  ZeitStart(tges);
  for i := 1 to 1000000 do
     begin
     ZeitStopp(tdummy);
     end;
  ZeitStopp(tges);
  WriteLn(Format(' Gesamttakte %12d ',[tges.tsum]));
  WriteLn(Format(' Gesamtzeit  %12.6f ms',[tges.tsum/CPUf]));
  WriteLn(Format(' Gesamtzahl  %12d ',[tdummy.StartStoppCnt]));
  Writeln;
end.
Gruß Horst

ferby 5. Jun 2008 20:48

Re: cpu zeit einer schleife auslesen
 
Hello,

thx,

werds so irgendwie machen ;-)

himitsu 5. Jun 2008 22:42

Re: cpu zeit einer schleife auslesen
 
zu Horst_s Vorschlag:
beim Messen mit dem TimeStampCounter muß man aber inzwischen höllisch aufpassen!

z.B.:
http://www.delphipraxis.net/internal...ighlight=rdtsc
und weitere Beiträge

Und ich glaube mal gehört zu haben, daß der auf einigen Prozessoren unabhängig vom CPU-Takt läuft,
was erstmal nicht sooo schlimm ist, aber ich laß z.B. meinen Prozessor dynamisch takten (heißt der Takt ändert sich je nach CPU-Auslastung) und da würde dann der gemessene Wert nicht unbedingt mit der CPU-Zeit übereinstimmen.

Horst_ 6. Jun 2008 06:04

Re: cpu zeit einer schleife auslesen
 
Hallo,

ich dachte es würden eben genau die Cpu-Takte gezählt.
Ob bei 800 Mhz oder 2200 Mhz. Die absolute Zeitdauer ist natürlich flexibel.
Bei Mehrfachkernen ist natürlich die Möglichkeit das WinAPI-aufrufe auf einem anderen Kern in anderer Frequenz laufen schon groß.
Aber ich gehe davon aus, das man nur seinen eigenen Algo testet, und dort nur einen sehr kurzen Abschnitt, sonst eben gettickcount.
Das bringt mich auf eine Idee:
Zusätzlich könnte man ja dtMin und dtMax bestimmen und eintragen. Dann weiß man, was man von den Daten zu halten hat.

Gruß Horst
P.S.: Mich haben eigentlich nur die Taktzahlen interessiert,.
Eine Taktmessung ist doch wenigstens für eine CPU machbar, auch bei unterschiedlicher Taktrate, die hat man doch nicht im Griff.

himitsu 6. Jun 2008 06:38

Re: cpu zeit einer schleife auslesen
 
RDTSC mißt im Prinzip nur dieProzessortakte, aber eben alle Takte wärend der Messung, incl. der Takte für die anderen, wärend der Messdauer laufenden Programme.

und da bei dynamisch getakteten CPUs diese Taktzyklen nicht genau einer bestimmten Zeiteinheit entsprechen, haben wohl einige CPU-Hersteller sich gedacht, sie erzeugen diesen über Zeitsynchron über einen externen/separaten Taktgenerator.


jedenfalls kommt es mir so vor, als wenn ich Dieses mal in Bezug auf die Messung der CPU-Geschwindigkeit gelesen zu hatte.
(wo man ja einfach über eine gewisse Zeit die "CPU"-Takte mißt)

Cyf 6. Jun 2008 13:11

Re: cpu zeit einer schleife auslesen
 
Zitat:

Zitat von Horst_
Delphi-Quellcode:
// EAX ist der Zeiger auf t und muss gerettet werden
  // Weil der Compiler sonst durcheinander kommt

Nur um Verwirrung vorzubeugen, der Zeiger muss hier nur gerettet werden, da später übe die Zugriffe auf t auf ihn (also EAX) zugegriffen wird, generell stehen EAX. EBX und EDX zur freien Verfügung.

RDTSC bringt, wie schon genannt, isbesondere auf Multicoresystemen und bei Energiesparfunktionen (Taktveränderung), oder auch bei "out-of-order execution" gewisse Probleme mit sich (siehe auch -> englische Wikipedia "RDTSC").
Wenn man diese Probleme nicht ausschließen kann, sind QueryPerformanceFrequency() + QueryPerformanceCounter(), denke ich, die bessere Alternative.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:13 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz