Jump to content
  • Advertisement
Sign in to follow this  
TerrorFLOP

Interpreting the CPU clock.

This topic is 4487 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This was raised in another thread (somewhere) but I cannot track it down. Anyway, I'll get straight to the point... I've been using QueryPerformanceFrequency and QueryPerformanceCounter for some time now in obtaining 'accurate' timings of code. However, in response to the original thread, someone suggested using the following asm code:
int time;
__asm
{
   cpuid
   rdtsc
   mov time, eax
}

I've been skimming through the Intel processor manuals, which indicates that the integer 'time' would contain the low-order 32 bits of the MSR (Model Specific Register), which in turn contains the number of elapsed clock cycles since the processor started. However, I'm trying to convert the number of clock cycles, between two snap-shots of the MSR, into microseconds and I was using QueryPerformanceFrequency to do it. But I seem to be getting some strange results when I time a null statement in Release builds: 0.18 microseconds using the rdtsc instruction (which is way too slow for a 3GHz PC like mine) 0.0019 microseconds using QueryPerformanceCounter (which seems nominal) Am I right in assuming rdtsc clock cycles and QueryPerformanceFrequency counts per second are actually related??? It's no big deal at the end of the day as I can always just stick to QueryPerformanceCounter. It just seemed (reading from the Intel manuals) that rdtsc would provide even more accurate timings, considering the cpuid instruction forces the CPU to finish all pending operations before placing the time-stamp in the MSR.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by TerrorFLOP
Am I right in assuming rdtsc clock cycles and QueryPerformanceFrequency counts per second are actually related???


No, not necessarily.

Share this post


Link to post
Share on other sites
It's okay. I got it sorted now :-)

Seemed I had to take into account the high-order bits of the MSR as follows:


inline LONGLONG CPU_Counter ()
{
LARGE_INTEGER counter;
__asm
{
cpuid
rdtsc
mov counter.LowPart, eax
mov counter.HighPart, edx
}
return counter.QuadPart;
}



Having run some tests, this approach to reading the CPU clock seems to be slightly more accurate than QueryPerformanceCounter, by an extra decimal place of accuracy (CPU_Counter seems accurate to within a tenth of a nano-second compared to QueryPerformanceCounter's accuracy of about one nano-second).

So I guess rdtsc clock cycles and QueryPerformanceCounter counts are indeed the same thing (which makes sense!).

Share this post


Link to post
Share on other sites
Doesn't query performance count (and all this stuff) break down in the face of speed step / power now technology?

I used this same syste in all my previous games, but when I got my Turion 64 laptop suddenly I would get unpredictable behavior (It can run as slow as 800 MHz or as fast as 1.6GHz). I never tracked this down to be 100% sure it was the timing system's fault, but I highly suspect it is.

Let me know if you find anything about this - especially if there is a newer prefered method that works in all of these enviroments.

Share this post


Link to post
Share on other sites
Quote:
Original post by LorenzoGatti
What is the initial cpuid instruction for?

It ensures that no other instructions are still being processed.

Share this post


Link to post
Share on other sites
Quote:
Original post by Xai
Doesn't query performance count (and all this stuff) break down in the face of speed step / power now technology?


AFAIK, QueryPerformanceCounter/Frequency should compensate as long as the proper cpu HAL drivers are installed. However, directly reading the MSR in your own inline assembly does not compensate. Most newer processors now have a high performance programmable timer that runs (mostly) independently of the cpu clock. QueryPerformanceCounter could utilize that to compensate if it is available.

Share this post


Link to post
Share on other sites
Quote:
Original post by Xai
Doesn't query performance count (and all this stuff) break down in the face of speed step / power now technology?

I used this same syste in all my previous games, but when I got my Turion 64 laptop suddenly I would get unpredictable behavior (It can run as slow as 800 MHz or as fast as 1.6GHz). I never tracked this down to be 100% sure it was the timing system's fault, but I highly suspect it is.

Let me know if you find anything about this - especially if there is a newer prefered method that works in all of these enviroments.


I'm pretty sure the Intel processor manuals would shed some light on this, as it's pretty in-depth and highly technical (collectively, they're almost 3000 pages!!!)

But since you're using an AMD, I doubt that these manuals could help.

Check out the AMD processor manuals if they're available.

Share this post


Link to post
Share on other sites
Quote:
Original post by TerrorFLOP
Quote:
Original post by Xai
Doesn't query performance count (and all this stuff) break down in the face of speed step / power now technology?

I used this same syste in all my previous games, but when I got my Turion 64 laptop suddenly I would get unpredictable behavior (It can run as slow as 800 MHz or as fast as 1.6GHz). I never tracked this down to be 100% sure it was the timing system's fault, but I highly suspect it is.

Let me know if you find anything about this - especially if there is a newer prefered method that works in all of these enviroments.


I'm pretty sure the Intel processor manuals would shed some light on this, as it's pretty in-depth and highly technical (collectively, they're almost 3000 pages!!!)

But since you're using an AMD, I doubt that these manuals could help.

Check out the AMD processor manuals if they're available.


This is a "normal" behavior - no need ti check the intel or AMD manuals. When the labtop wants to reduce its energy , it may reduces the CPU frequency. I believe you can change this behavior using the Windows control pannel. Now, if you know the correct frequency at a given time, the problem vanishes.

Regards,

Share this post


Link to post
Share on other sites
??? exactly how would you know the correct frequency?

No offense people, but I'm not looking for hints at things that might work when I find them ... that might be appropriate if I was 80% done with some task and just needed to find a way to get it working ... but that's not the way I work.

I'm looking for "the right answer" .. or any of the set of "guaranteed to work correctly in all cases" answers.

Surely someone here has some experience in this area and can either point to some links on how to do this type of thing, answer definitively if it works a certain way (officially), or express the pain they had to go through to solve the problem themselves and therefore why no simple - normal - dependable solution exists as far as they know.

I have no interests in learning and repeating half solutions to solvable problems. But if the problem hasn't been solved (cleanly) - then maybe I'll look into finding a correct solution myself.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!