Page 1 of 1

Reading time from the high-resolution performance counter

Posted: Fri Jan 27, 2012 10:17 pm
by fips
Since I've been recently in an urgent need of having a precise time source on Windows, I wrote the routine blow involving QueryPerformanceCounter. Luckily, I had recalled the problems of reading from the counter across multiple cores and resolved the issue as shown below:

Code: Select all

double time_sec()
{
    static bool inited = false;
    static double freq;

    if(!inited)
    {
        LARGE_INTEGER freq64;

        if(!QueryPerformanceFrequency(&freq64))
            FS_THROW(Exception("High-resolution performance counter not available!"));

        freq = double(freq64.QuadPart);
        inited = true;
    }

    // force the current thread to run on CPU1 in order to consistently read
    // the high-res counter on the same core, otherwise it's inaccurate
    //! \todo Check how this affect performance.
    const HANDLE current_thread = GetCurrentThread();
    const DWORD_PTR orig_affinity = SetThreadAffinityMask(current_thread, 1);
    LARGE_INTEGER time;
    FS_ASSERT(orig_affinity);
    FS_VERIFY(QueryPerformanceCounter(&time));
    FS_VERIFY(SetThreadAffinityMask(current_thread, orig_affinity)); // restore

    return double(time.QuadPart) / freq;
}