Here is a snippet of code from Quake I.
LARGE_INTEGER PerformanceFreq;
unsigned int lowpart, highpart;
OSVERSIONINFO vinfo;
if (!QueryPerformanceFrequency (&PerformanceFreq))
Sys_Error ("No hardware timer available");
// get 32 out of the 64 time bits such that we have around 1 microsecond resolution
lowpart = (unsigned int)PerformanceFreq.LowPart;
highpart = (unsigned int)PerformanceFreq.HighPart;
lowshift = 0;
while (highpart || (lowpart > 2000000.0))
{
lowshift++;
lowpart >>= 1;
lowpart |= (highpart & 1) << 31;
highpart >>= 1;
}
The comment indicates that they are reducing the 64 bit PerformanceFreq
to 32 bits and that the resolution is about 1 microsecond (the default resolution of QueryPerformanceFrequency is 1 second).
I understand what the code is doing generally, but I don't know what (lowpart > 2000000.0)
is meant to be doing or why it's there. I think it's related to ensuring the resolution is about 1 microsecond.
When I run this code through the debugger the lowpart
is shifted 3 times meaning that the resolution is actually 1s / 2^3 - 0.125s or 125 milliseconds and not 1 microsecond. The documentation for QueryPerformanceFrequency
says that the result is hardware dependent so I don't see how a constant value 200000.0
could work unless you were making an assumption for the result based on modern hardware of the time.
Is this code wrong about the resolution or am I missing something?