this slowpoke moves

Get CPU Clock Speed in many ways

Die folgenden drei Beispiele demonstrieren, auf welche unterschiedlicher Weise der CPU-Takt ermittelt werden kann.

Das erste Beispiel rundet den Takt auf 1 MHz ab oder auf.

Das zweite Beispiel liefert das Formatergebnis auf eine Stelle rechts von Komma.

Das dritte Beispiel ermittelt den ganz genauen Takt des CPUs bis auf sechs Stellen rechts vom Komma, also 0,000001 Hz.
function CPUSpeed: Double;
const
    DelayTime = 500;
var
    TimerHi, TimerLo: DWORD;
    PriorityClass, Priority : Integer;
begin
  PriorityClass:=GetPriorityClass(GetCurrentProcess);
  Priority:=GetThreadPriority(GetCurrentThread);
  SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
  Sleep(10);
  asm
    dw 310Fh
    mov TimerLo, eax
    mov TimerHi, edx
  end;

  Sleep(DelayTime);
  asm
    dw 310Fh
    sub eax, TimerLo
    sbb edx, TimerHi
    mov TimerLo, eax
    mov TimerHi, edx
  end;

  SetThreadPriority(GetCurrentThread, Priority);
  SetPriorityClass(GetCurrentProcess, PriorityClass);
  Result := TimerLo / (1000 * DelayTime);
end;

function get_cpu_speed:dword;
var Speed : dword;
    perform: int64;
begin
 perform:=0;
 SetpriorityClass(getcurrentprocess,REALTIME_PRIORITY_CLASS);
 SetThreadPriority(getcurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
 asm
   push eax
   push edx
   push ecx
   push 1000
   call sleep      // appel de sleep(1000)
   dw   $310F      // rdtsc (red internal cpu timer in cycle)
   add  eax,edx
   mov  speed,eax  // stokez les cycles machine
   push edx
   xor  eax,eax
   push 1000
   call sleep      // appel de sleep(1000)
   pop  edx
   dw   $310F      // relire le timer cpu rdsc
   add  eax,edx
   sub  eax,speed  // garder 1000 millisecondes (1 seconde)
   mov  speed,eax  // le stocké dans speed;
   pop  ecx
   pop  edx
   pop  eax
 end;
 result:=round((speed / 1000000) / 3)*3; // div 3 * 3 a cose de busfeq
end;

function GetCpuSpeed: Comp;
{ function to return the CPU clock speed only.                                     }
{ Usage: MessageDlg(Format('%.1f MHz', [GetCpuSpeed]), mtConfirmation, [mbOk], 0); }
var
   t: DWORD;
   mhi, mlo, nhi, nlo: DWORD;
   t0, t1, chi, clo, shr32: Comp;
begin
   shr32 := 65536;
   shr32 := shr32 * 65536;

   t := GetTickCount;
   while t = GetTickCount do begin end;
   asm
     DB 0FH
     DB 031H
     mov mhi,edx
     mov mlo,eax
   end;

   while GetTickCount < (t + 1000) do begin end;
   asm
     DB 0FH
     DB 031H
     mov nhi,edx
     mov nlo,eax
   end;

   chi := mhi;
   if mhi < 0 then
   chi := chi + shr32;
   clo := mlo;

   if mlo < 0 then
   clo := clo + shr32;
   t0 := chi * shr32 + clo;
   chi := nhi;

   if nhi < 0 then
   chi := chi + shr32;
   clo := nlo;

   if nlo < 0 then clo := clo + shr32;
   t1 := chi * shr32 + clo;

   Result := (t1 - t0) / 1E6;
end;


// Aufrunden der Taktung
procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := IntToStr(get_cpu_speed);
end;

// Format Abruf und Ausaabe
procedure TForm1.Button2Click(Sender: TObject);
begin
  Label1.Caption := Format('%.1f MHz', [GetCpuSpeed]);
end;

// Sehr genaue Berechnung des CPU Takts
procedure TForm1.Button3Click(Sender: TObject);
begin
  Label1.Caption := FloatToStr(CPUSpeed);
end;

Keine Kommentare:

Kommentar veröffentlichen

Beliebte Posts

Translate