AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein CPU Speed Assembler & Delphi - Was passiert da?
Thema durchsuchen
Ansicht
Themen-Optionen

CPU Speed Assembler & Delphi - Was passiert da?

Ein Thema von psd-sign · begonnen am 25. Jun 2009 · letzter Beitrag vom 25. Jun 2009
Antwort Antwort
psd-sign

Registriert seit: 3. Nov 2008
31 Beiträge
 
#1

CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 02:02
Hiermit ermittle ich die CPU Geschwindigkeit. Eine nicht ganz unbekannte Assembler Routine in DElphi eingebunden .... ich gebe aber ehrlich zu: Ich verstehe den CODE nich zu 100%!!

Delphi-Quellcode:
function CPU_SPEED_FLOAT: Extended;
const
  DelayTime = 500; // measure time in ms
var
  TimerHi, TimerLo: DWord;
  PriorityClass, Priority: Integer;
begin
  try
    PriorityClass := GetPriorityClass(GetCurrentProcess);
    Priority := GetThreadPriority(GetCurrentThread);

    SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
    SetThreadPriority(GetCurrentThread,
                      THREAD_PRIORITY_TIME_CRITICAL);
    try
      Sleep(10);
      asm
        dw 310Fh // rdtsc
        mov TimerLo, eax
        mov TimerHi, edx
      end;
      Sleep(DelayTime);
      asm
        dw 310Fh // rdtsc
        sub eax, TimerLo
        sbb edx, TimerHi
        mov TimerLo, eax
        mov TimerHi, edx
      end;
    finally
      SetThreadPriority(GetCurrentThread, Priority);
      SetPriorityClass(GetCurrentProcess, PriorityClass);
    end;
    Result := TimerLo / (1000.0 * DelayTime);
  except
    Result := 0;
  end;
end;

Warum setze bzw. operiere ich mit "TimerHi"? ... Kann jemand mir den CODE auskommentieren bzw. erklären, was ich mit den Registern wirklich mache und warum ich "TimerHi" in der Ausgabe nicht nutze? Wenn die Tutorial und Programmier-Cracks wie Luckie & Co einen Augenblick Zeit haben, würde ich mich freuen ... mag es nicht, Code zu verwenden, den ich nicht zu 100% verstehe.
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#2

Re: CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 02:55
Ich bin jetzt kein Programmiercrack, wie Luckie und Co, aber ich antworte trotzdem mal. Der Luckie is nämlich schon müde .

Bevor es los geht:
Wie ist Hertz definiert? Nun, Wikipedia sagt uns: Hertz gibt die Schwingungen (bei Prozessoren spricht man von Zyklen) pro Sekunde an. Ein Megahertz sind entsprechend eine Million Zyklen pro Sekunde und ein Gigahertz sind eine Milliarde Zyklen pro Sekunde.

Außerdem einen kurzen Exkurs zum RDTSC (ReaD TSC) Befehl. Der Befehl wurde mit der Pentium Prozessorklasse eingeführt. Prinzipiel kann man mit ihm den Time Stamp Counter auslesen. Der Time Stamp Counter ist dabei ein 64bit großer Zähler, der mit jedem Zyklus um eins inkrementiert wird. Ich denke Du wirst jetzt schon erahnen worauf der Code hinaus läuft ...

Delphi-Quellcode:
function CPU_SPEED_FLOAT: Extended;
const
  DelayTime = 500; // measure time in ms
var
  TimerHi, TimerLo: DWord;
  PriorityClass, Priority: Integer;
begin
  try
    // Zuerst einmal sichern wir die alten Prioritäten für unseren Prozess bzw. Thread, damit wir unsere Änderungen rückgängig machen können ...
    PriorityClass := GetPriorityClass(GetCurrentProcess);
    Priority := GetThreadPriority(GetCurrentThread);

    // ... und dann sagen wir Windows das wir derart wichtig sind, daß wir möglichst vor allen anderen Threads und Anwendungen ausgeführt werden wollen.
    SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
    SetThreadPriority(GetCurrentThread,
                      THREAD_PRIORITY_TIME_CRITICAL);
    try
      Sleep(10);
      // Wir holen uns als erstes den aktuellen Zykluszähler. Da der Zähler ein 64bit Wert ist, wir aber nur 32bit Register haben, muss der Zähler
      // auf 2 Register verteilt werden. In EAX landen die Low Order Bits und in EDX die High Order Bits.
      asm
        dw 310Fh // rdtsc
        // Da wir die später nochmal brauchen werden, müssen die aber noch gesichert werden: Die Low Bits in TimerLo und die High Bits in TimerHi.
        mov TimerLo, eax
        mov TimerHi, edx
      end;
      // Und dann warten wir einen definierten Zeitraum ...
      Sleep(DelayTime);
      // Um danach den Zähler nochmal auszulesen ...
      asm
        dw 310Fh // rdtsc
        // ... und die Differenz aus den neuen Werten und den gespeicherten zu berechnen ...
        sub eax, TimerLo
        sbb edx, TimerHi
        // ... die wir dann auch direkt in unsere Timer* Variablen packen.
        mov TimerLo, eax
        mov TimerHi, edx
      end;
    finally
      // Da wir nicht ewig mit Echtzeit Priorität laufen dürfen, weil der User sonst böse Mails schreibt, werden die Prioritäten wieder zurückgesetzt.
      SetThreadPriority(GetCurrentThread, Priority);
      SetPriorityClass(GetCurrentProcess, PriorityClass);
    end;
    // Hier gibts einen Bug. Zur Berechnung wird nur TimerLo herangezogen, was falsch ist. Man müsste auf TimerHi und TimerLo wieder einen
    // 64bit Wert bauen um mit dem zu rechnen. Ab einer bestimmten Geschwindigkeit wird der Code also nicht mehr korrekt funktionieren.
    // Aber egal ... da Hertz die Anzahl der Zyklen in Sekunden angibt und wir wissen, wieviele Zyklen im von uns gestoppten Zeitraum
    // durchlaufen wurden, rechnen wir das ganze um (in Megahertz übrigens ;)).
    Result := TimerLo / (1000.0 * DelayTime);
  except
    Result := 0;
  end;
end;
Und ja ... da wars. Bei weiteren Fragen, einfach stellen.
Fridolin Walther
"While Mr. Kim, by virtue of youth and naiveté, has fallen prey to the inexplicable need for human contact, let me step in and assure you that my research will go on uninterrupted, and that social relationships will continue to baffle and repulse me."
  Mit Zitat antworten Zitat
psd-sign

Registriert seit: 3. Nov 2008
31 Beiträge
 
#3

Re: CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 03:14
Mit anderen Worten, müsste ich das Result so ausgeben??
Result := (TimerLo + TimerHi / (1000.0 * DelayTime);
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#4

Re: CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 03:18
Zitat von psd-sign:
Mit anderen Worten, müsste ich das Result so ausgeben??
Result := (TimerLo + TimerHi / (1000.0 * DelayTime);
Nein ... Du müsstest einen ULARGE_INTEGER definieren (einen 64bit Typ) und den HighPart und LowPart entsprechend setzen.

Hier mal eine fehlerbereinigte Version:
Delphi-Quellcode:
function GetProcessorSpeed(TimeToWait : Cardinal) : Cardinal;
var
  TickCountFirst, TickCountSecond : Cardinal;
  CycleCountFirst, CycleCountSecond : ULARGE_INTEGER;
begin
  TickCountFirst := GetTickCount;

  // Erster Meßpunkt
  asm
    dw 310Fh // rdtsc
    mov CycleCountFirst.LowPart, eax
    mov CycleCountFirst.HighPart, edx
  end;

  sleep(TimeToWait);
  TickCountSecond := GetTickCount;

  // Zweiter Meßpunkt
  asm
    dw 310Fh // rdtsc
    mov CycleCountSecond.LowPart, eax
    mov CycleCountSecond.HighPart, edx
  end;

  result := (CycleCountSecond.QuadPart - CycleCountFirst.QuadPart) div ((TickCountSecond - TickCountFirst) * 1000);
end;
Die Funktion empfiehlt sich übrigens nicht zum messen. Stromsparfunktionen etc. verfälschen das Ergebnis. Wenn Du die wirkliche Frequenz haben willst, solltest Du WMI bemühen .
Fridolin Walther
"While Mr. Kim, by virtue of youth and naiveté, has fallen prey to the inexplicable need for human contact, let me step in and assure you that my research will go on uninterrupted, and that social relationships will continue to baffle and repulse me."
  Mit Zitat antworten Zitat
psd-sign

Registriert seit: 3. Nov 2008
31 Beiträge
 
#5

Re: CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 03:20
W M I ... wieder die böse Abkürzung ... .

Dank Dir für die Antwort zu so später Stunde
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#6

Re: CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 03:29
Zitat von psd-sign:
W M I ... wieder die böse Abkürzung ... .
So schlim ist WMI gar nicht. Kannst ja mal Suchen hier im Board. Jaenicke hatte da eine recht hübsche Funktion geposted glaube ich .

Zitat von psd-sign:
Dank Dir für die Antwort zu so später Stunde
Wieso spät? Früh!
Fridolin Walther
"While Mr. Kim, by virtue of youth and naiveté, has fallen prey to the inexplicable need for human contact, let me step in and assure you that my research will go on uninterrupted, and that social relationships will continue to baffle and repulse me."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

Re: CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 09:25
wozu WMI ... WMI ließt auch nur dieses hier aus:
http://www.delphipraxis.net/internal...=488470#488470

dann ist Sleep nicht grade genau, drum lesen viele zusätzlich noch mit den QueryPerformanceCounter die tatsächliche Pause-Zeit aus
http://www.delphipraxis.net/internal...ighlight=rdtsc

außerdem zeigt dein Code bei mehr als einer CPU eventuell was Falsches an:
http://www.delphipraxis.net/internal...ighlight=rdtsc

PS:
http://www.delphipraxis.net/internal...ighlight=rdtsc
ja, ich nutze immernoch Cool&Quite

PSS: auch wenn's nichts Schlimmes ist, warum geben fast alle immernoch RDTSC als Bytecode an?
der Delphicompiler kennt diesen ASM-Befehl schon seit seeeeeeeehr vielen Jahren
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#8

Re: CPU Speed Assembler & Delphi - Was passiert da?

  Alt 25. Jun 2009, 11:21
Zitat von himitsu:
PSS: auch wenn's nichts Schlimmes ist, warum geben fast alle immernoch RDTSC als Bytecode an?
der Delphicompiler kennt diesen ASM-Befehl schon seit seeeeeeeehr vielen Jahren
Steht seine Delphi Version dabei? I don't think so . Es gibt Delphi Versionen, die den Bytecode nicht kennen .
Fridolin Walther
"While Mr. Kim, by virtue of youth and naiveté, has fallen prey to the inexplicable need for human contact, let me step in and assure you that my research will go on uninterrupted, and that social relationships will continue to baffle and repulse me."
  Mit Zitat antworten Zitat
Antwort Antwort


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 10:21 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