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