Reading time from the high-resolution performance counter
Posted: Fri Jan 27, 2012 10:17 pm
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;
}