High-precision CPU clock speed routine, 64-bit Windows only

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

High-precision CPU clock speed routine, 64-bit Windows only

Post by MichaelW »

Code: Select all

#include "windows.bi"

function ClockSpeed() as double

    dim as LARGE_INTEGER pf, pc1, pc2, cc1, cc2
    dim as DWORD_PTR processAffinityMask, systemAffinityMask
    dim as DWORD priorityClass
    dim as long threadPriority
    dim as double freq, giga = 1000000000.0
    
    GetProcessAffinityMask( GetCurrentProcess(), @processAffinityMask, @systemAffinityMask )
    
    '' Restrict process to running on a single core to avoid problems
    '' with the core time-stamp counters being out of sync.
    
    SetProcessAffinityMask( GetCurrentProcess(), 1)
    
    priorityClass = GetPriorityClass( GetCurrentProcess() )
    threadPriority = GetThreadPriority( GetCurrentThread() )
    
    '' Maximize process and thread priorities to minimize interruptions.
    
    SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS )
    SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL )
    
    QueryPerformanceFrequency( @pf )
    
    sleep 2000
    
    '' For RDTSC, on processors that support 64-bit instructions the high-
    '' order 32 bits of RAX and RDX are cleared, so the returned EAX and
    '' EDX values can be combined into a QWORD simply, with SHL and OR.
   
    asm
        xor     eax, eax
        cpuid
        rdtsc
        shl     rdx, 32
        or      rdx, rax
        mov     [cc1], rdx    
    end asm
    
    QueryPerformanceCounter( @pc1 )
    
    sleep 2000
    
    asm
        xor     eax, eax
        cpuid
        rdtsc
        shl     rdx, 32
        or      rdx, rax
        mov     [cc2], rdx    
    end asm   
    
    QueryPerformanceCounter( @pc2 )
    
    SetProcessAffinityMask( GetCurrentProcess(), processAffinityMask )
    
    SetPriorityClass( GetCurrentProcess(), priorityClass )
    SetThreadPriority( GetCurrentThread(), threadPriority )
    
    '' elapsed counter cycles = pc2.QuadPart - pc1.QuadPart
    '' elapsed seconds = elapsed counter cycles / pf.QuadPart
    '' elapsed clock cycles = cc2.QuadPart - cc1.QuadPart
    '' clock speed = elapsed cycles / elapsed seconds
    
    return ((cc2.QuadPart-cc1.QuadPart)/((pc2.QuadPart-pc1.QuadPart)/pf.QuadPart))/giga

end function

print using "###.######GHz";ClockSpeed

sleep
Post Reply