注册表不是一个好的解决方案,因为它可能会被更改并且可能需要用户许可(读取注册表)。
以下代码可以在 32 位和 64 位的 Delphi XE-8 下编译,遵循 SAME 原则,因此这应该在 32 位和 64 位中为您提供一致的值。
{$IFDEF CPUX64}
function GetCpuClockCycleCount: Int64; assembler; register;
asm
dw 310Fh // rdtsc
shl rdx, 32
or rax, rdx
end;
{$ENDIF}
function GetCPUSpeed: double;
{$IFDEF CPUX86}
const
DelayTime = 500; // measure time in ms
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 // 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;
SetthreadPriority(GetCurrentthread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := TimerLo / (1000.0 * DelayTime);
end;
{$ELSE}
const
DelayTime = 500;
var
x, y: UInt64;
PriorityClass, Priority: Integer;
begin
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
x := GetCpuClockCycleCount;
Sleep(DelayTime);
y := GetCpuClockCycleCount;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := ((y - x) and $FFFFFFFF) / (1000 * DelayTime);
end;
{$ENDIF}