   QueryPerformanceCounter horror
  Hi! I'm having a lot of problems using QPC for profiling purposes. I've read a lot about QPC problems, but I cannot figure out a better way. I'm trying to stick the thread to a single CPU core, but the problems with QPC still remain. I have a Core i7 930 processor (4 core/8 thread).int _tmain(int argc, _TCHAR* argv[]){    ::SetThreadAffinityMask(::GetCurrentThread(), 1);    ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );    __int64 lFreq = 0;    ::QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>(&lFreq) );    float lSecPerCount = 1.0f/(float)lFreq;    __int64 lOldTimeStamp = 0;    ::QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>(&lOldTimeStamp) );    for (int i = 0; i < 100; ++i)    {   __int64 lCurrentTimeStamp = 0;   ::QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>(&lCurrentTimeStamp) );   float lTimeDiff = (lCurrentTimeStamp - lOldTimeStamp) * lSecPerCount * 1000.0f;   std::cout << lTimeDiff << std::endl;   lOldTimeStamp = lCurrentTimeStamp;   static float acc = 1.01f;   for (int j = 0; j < 100000; ++j)   {  acc *= 0.1f;   }    }    ::getchar();return 0;}Executing the previous code snippet I always get spikes, for instance:0.5077070.5077070.5033710.6168370.5452880.5214390.511682The error is too significant if we want to test some of our game subsystems... Besides, the error grows as the time elapsed is longer.Do you know any solution? Thanks!   
  I'd recommend reading This.   ;Quote:Original post by Evil SteveI'd recommend reading This.As far as I understand there shouldn't be any problems with QPC when you make sure you only check timers on a single CPU (like Nene is doing). Following is from the QPC documentation:Quote:On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL).I don't think there's anything wrong with his timing code, it's just that some other process/thread is eating his CPU resources... Maybe a (probably misbehaving) driver.Just learn to live with the fact that timers aren't an exact science on a desktop OS.   ;Quote:    __int64 lFreq = 0;    ::QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>(&lFreq) );    float lSecPerCount = 1.0f/(float)lFreq;I think i can see an issue hereOn 64bits architecture__int64 is 64 bfloat is 32bQuote:(float)lFreq;here we cast a 64b value in a 32 bit containerMaybe i'm wrong, but for me it's a problem   ;Quote:Original post by rneckelmannAs far as I understand there shouldn't be any problems with QPC when you make sure you only check timers on a single CPU (like Nene is doing).[snip]I don't think there's anything wrong with his timing code, it's just that some other process/thread is eating his CPU resources... Maybe a (probably misbehaving) driver.Performance counter value may unexpectedly leap forward.   ;  I've tried the same example using timeGetTime and GetTickCount, and it still has problems. Look at this:int _tmain(int argc, _TCHAR* argv[]){   DWORD dwCurrent;   DWORD dwLast;   DWORD dwTickElapsed;    dwCurrent = dwLast = GetTickCount();    for (int i = 0; i < 100; ++i)    {   dwCurrent = GetTickCount();   dwTickElapsed = dwCurrent - dwLast;   std::cout << dwTickElapsed << std::endl;   dwLast = dwCurrent;    }    return 0;}This returns the following result!000150160160150160150016000160001500016001500016000160001500160001500016000160015000160001500016001600015000160001500160001600015and so on... if I put a Sleep(1); then it works well...   ;Quote:Original post by NeneExecuting the previous code snippet I always get spikes, for instance:Are you sure these spikes are bugs in the timer, and it isn't that sometimes the loop actually does take longer to complete?Quote:Original post by Christuffhere we cast a 64b value in a 32 bit containerMaybe i'm wrong, but for me it's a problemIt's not usually a problem, but I have been burned by this in the past so I usually use doubles inside my timer classes these days.   ;  For those who don't know, QPC is actually the number of cycles executed by the CPU since startup (You can trace the assembly to find the Opcode). This is literally a pentium opcode that is called and filled into the results of a 64-bit buffer. I DO NOT recommend using this for any time sensitive source code for the following reasons:1) CPU clock frequency is dynamic on some CPU's (Especially mobile ones).2) Threads could be running on different CPUs at any time depending on how they're setup giving you a different result at time of execution.3) Granularity is system dependant. 2GHZ machine vs 800mhz, etc. Even though you can get the clock frequency, it just gives different results which isn't fun ;)Depending on your OS there may be better time sensitive measuring APIs.   ;Quote:Original post by GodBeastXFor those who don't know, QPC is actually the number of cycles executed by the CPU since startup (You can trace the assembly to find the Opcode). This is literally a pentium opcodeNo.What you're thinking of is the rdtsc instruction which does do what you describe.  However it is not what typically drives QueryPerformanceCounter, precisely because it has all those problems as well as not being syncronized across multiple processors.  If you look around you'll see MS contantly telling people not to use rdtsc.Having said that, QPC can use rdtsc if it's appropriate to do so for your machine configuration.The thing that makes QPC problematic is that there are tons of buggy HAL's and a ton more of buggy hardware.  QPC is very much at the mercy of several different subsystems to do everything just right.  Unfortunately it's quite common for hardware to have issues (especially high-performance hardware) and it's even more common for hardware drivers to absolute sh*t.  This isn't obvious to your typical user because all major OS's go out of their way to cover this sort of thing up.  It's also extremely difficult for most users (even relatively technical ones) to correlate the problems that they do see with the root cause of those problems.   ;Quote:Original post by GodBeastX.....Depending on your OS there may be better time sensitive measuring APIs.I've taken a timeout since the single-core days and back then I never considered anything else then QPC. Any suggestesions of good alternatives for a reliable timer is appreciated. The OS in question would be Windows 7 or XP. 