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

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

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

Postby MichaelW » Oct 31, 2015 17:24

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

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 1 guest