unit JclSysInfo; ..... Current function version: //-------------------------------------------------------------------------------------------------- function GetCPUSpeed(var CpuSpeed: TFreqInfo): Boolean; var T0, T1: TULargeInteger; CountFreq: TULargeInteger; Freq, Freq2, Freq3, Total: Integer; TotalCycles, Cycles: Int64; Stamp0, Stamp1: Int64; TotalTicks, Ticks: Cardinal; Tries, Priority: Integer; Thread: THandle; begin Stamp0 := 0; Stamp1 := 0; Freq := 0; Freq2 := 0; Freq3 := 0; Tries := 0; TotalCycles := 0; TotalTicks := 0; Total := 0; Thread := GetCurrentThread(); Result := QueryPerformanceFrequency(Int64(CountFreq)); if Result then begin while ((Tries < 3 ) or ((Tries < 20) and ((Abs(3 * Freq - Total) > 3) or (Abs(3 * Freq2 - Total) > 3) or (Abs(3 * Freq3 - Total) > 3)))) do begin Inc(Tries); Freq3 := Freq2; Freq2 := Freq; QueryPerformanceCounter(Int64(T0)); T1.LowPart := T0.LowPart; T1.HighPart := T0.HighPart; Priority := GetThreadPriority(Thread); if Priority <> THREAD_PRIORITY_ERROR_RETURN then SetThreadPriority(Thread, THREAD_PRIORITY_TIME_CRITICAL); try while (T1.LowPart - T0.LowPart) < 50 do begin QueryPerformanceCounter(Int64(T1)); Stamp0 := ReadTimeStampCounter; end; T0.LowPart := T1.LowPart; T0.HighPart := T1.HighPart; while (T1.LowPart - T0.LowPart) < 1000 do begin QueryPerformanceCounter(Int64(T1)); Stamp1 := ReadTimeStampCounter; end; finally if Priority <> THREAD_PRIORITY_ERROR_RETURN then SetThreadPriority(Thread, Priority); end; Cycles := Stamp1 - Stamp0; Ticks := T1.LowPart - T0.LowPart; Ticks := Ticks * 100000; Ticks := Round(Ticks / (CountFreq.LowPart / 10)); TotalTicks := TotalTicks + Ticks; TotalCycles := TotalCycles + Cycles; Freq := Round(Cycles / Ticks); Total := Freq + Freq2 + Freq3; end; Freq3 := Round((TotalCycles * 10) / TotalTicks); Freq2 := Round((TotalCycles * 100) / TotalTicks); if Freq2 - (Freq3 * 10) >= 6 then Inc(Freq3); CpuSpeed.RawFreq := Round(TotalCycles / TotalTicks); CpuSpeed.NormFreq := CpuSpeed.RawFreq; Freq := CpuSpeed.RawFreq * 10; if (Freq3 - Freq) >= 6 then Inc(CpuSpeed.NormFreq); CpuSpeed.ExTicks := TotalTicks; CpuSpeed.InCycles := TotalCycles; CpuSpeed.NormFreq := RoundFrequency(CpuSpeed.NormFreq); Result := True; end; end; Repaired function version: //-------------------------------------------------------------------------------------------------- function GetCPUSpeed(var CpuSpeed: TFreqInfo): Boolean; var T0, T1: TULargeInteger; CountFreq: TULargeInteger; Freq, Freq2, Freq3, Total: Integer; TotalCycles, Cycles: Int64; Stamp0, Stamp1: Int64; TotalTicks, Ticks: Cardinal; Tries, Priority: Integer; Thread: THandle; begin Stamp0 := 0; Stamp1 := 0; Freq := 0; Freq2 := 0; Freq3 := 0; Tries := 0; TotalCycles := 0; TotalTicks := 0; Total := 0; Thread := GetCurrentThread(); Result := QueryPerformanceFrequency(Int64(CountFreq)); if Result then begin while ((Tries < 3 ) or ((Tries < 20) and ((Abs(3 * Freq - Total) > 3) or (Abs(3 * Freq2 - Total) > 3) or (Abs(3 * Freq3 - Total) > 3)))) do begin Inc(Tries); Freq3 := Freq2; Freq2 := Freq; QueryPerformanceCounter(Int64(T0)); T1.LowPart := T0.LowPart; T1.HighPart := T0.HighPart; Priority := GetThreadPriority(Thread); if Priority <> THREAD_PRIORITY_ERROR_RETURN then SetThreadPriority(Thread, THREAD_PRIORITY_TIME_CRITICAL); try while (T1.LowPart - T0.LowPart) < 50 do begin QueryPerformanceCounter(Int64(T1)); Stamp0 := ReadTimeStampCounter; end; T0.LowPart := T1.LowPart; T0.HighPart := T1.HighPart; while (T1.LowPart - T0.LowPart) < 1000 do begin QueryPerformanceCounter(Int64(T1)); Stamp1 := ReadTimeStampCounter; end; finally if Priority <> THREAD_PRIORITY_ERROR_RETURN then SetThreadPriority(Thread, Priority); end; Cycles := Stamp1 - Stamp0; Ticks := T1.LowPart - T0.LowPart; Ticks := Ticks * 100000; Ticks := Round(Ticks / (CountFreq.LowPart / 10)); TotalTicks := TotalTicks + Ticks; TotalCycles := TotalCycles + Cycles; if Ticks>0 then Freq := Round(Cycles / Ticks) else Freq := 0; Total := Freq + Freq2 + Freq3; end; if TotalTicks>0 then Freq3 := Round((TotalCycles * 10) / TotalTicks) else Freq3 := 0; if TotalTicks>0 then Freq2 := Round((TotalCycles * 100) / TotalTicks) else Freq2 := 0; if Freq2 - (Freq3 * 10) >= 6 then Inc(Freq3); if TotalTicks>0 then CpuSpeed.RawFreq := Round(TotalCycles / TotalTicks) else CpuSpeed.RawFreq := 0; CpuSpeed.NormFreq := CpuSpeed.RawFreq; Freq := CpuSpeed.RawFreq * 10; if (Freq3 - Freq) >= 6 then Inc(CpuSpeed.NormFreq); CpuSpeed.ExTicks := TotalTicks; CpuSpeed.InCycles := TotalCycles; CpuSpeed.NormFreq := RoundFrequency(CpuSpeed.NormFreq); Result := True; end; end;