Windows - calcular velocidade do cpu

Top  Previous  Next

Question/Problem/Abstract:

 

How to "judge" or read the CPU speed of a processor that a program is running on

Answer:

  This should the job. It will only give result with Pentium or better due to 

the RDTSC opcode. An alternative is to use QueryPerformanceCounter or QueryPerformanceFrequency from the WinAPI. 

 

function GetCPUSpeed: real; 

 

  function IsCPUID_Available: Boolean; assembler; register; 

  asm 

            PUSHFD               { direct access to flags not possible, only via stack } 

            POP    EAX           { flags to EAX } 

            MOV    EDX,EAX       { save current flags } 

            XOR    EAX,$200000   { not ID bit } 

            PUSH   EAX           { onto stack } 

            POPFD                { from stack to flags, with not ID bit } 

            PUSHFD               { back to stack } 

            POP    EAX           { get back to EAX } 

            XOR    EAX,EDX       { check if ID bit affected } 

            JZ     @exit         { no, CPUID not availavle } 

            MOV    AL,True       { Result=True } 

            @exit

  end

 

  function hasTSC: Boolean; 

  var 

    Features: Longword; 

  begin 

    asm 

              MOV    Features,0   { Features = 0 } 

 

              PUSH   EBX 

              XOR    EAX,EAX 

              DW     $A20F 

              POP    EBX 

 

              CMP    EAX,$01 

              JL     @Fail 

 

              XOR    EAX,EAX 

              MOV    EAX,$01 

              PUSH   EBX 

              DW     $A20F 

              MOV    Features,EDX 

              POP    EBX 

              @Fail: 

    end

 

    hasTSC := (Features and $10) <> 0

  end

 

const 

  DELAY = 500

var 

  TimerHi, TimerLo: Integer; 

  PriorityClass, Priority: Integer; 

begin 

  Result := 0

  if not (IsCPUID_Available and hasTSC) then Exit

  PriorityClass := GetPriorityClass(GetCurrentProcess); 

  Priority := GetThreadPriority(GetCurrentThread); 

 

  SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS); 

  SetThreadPriority(GetCurrentThread, 

    THREAD_PRIORITY_TIME_CRITICAL); 

 

  SleepEx(10, FALSE); 

 

  asm 

            DB     $0F           { $0F31 op-code for RDTSC Pentium instruction } 

            DB     $31           { returns a 64 Bit Integer } 

            MOV    TimerLo,EAX 

            MOV    TimerHi,EDX 

  end

 

  SleepEx(DELAY, FALSE); 

 

  asm 

            DB     $0F           { $0F31 op-code for RDTSC Pentium instruction } 

            DB     $31           { returns a 64 Bit Integer } 

            SUB    EAX,TimerLo 

            SBB    EDX,TimerHi 

            MOV    TimerLo,EAX 

            MOV    TimerHi,EDX 

  end

 

  SetThreadPriority(GetCurrentThread, Priority); 

  SetPriorityClass(GetCurrentProcess, PriorityClass); 

  Result := TimerLo / (1000 * DELAY); 

end