Can somebody please explain QueryPerformanceCounter?

Started by
9 comments, last by Dave Hunt 18 years, 8 months ago
I'm trying to make my game framerate independant (so the game runs at the same speed on all computers). After reading several tutorials I am still confused but instead of asking for an explanation, I'd only like for somebody to explain QueryPerformanceCounter to me. Let me start off by saying that QueryPerformanceCounter on my computer returns 3579545. I understand that to get the current time I should divide QueryPerformanceCounter / QueryPerformanceFrequency. With that said, what exactly is QueryPerformanceCounter? I know it's a "high resolution timer" but what does that mean? Does the time it returns loop? (can I get the same values twice?)
Advertisement
Quote:From QueryPerformanceCounter Function
The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter.
It is basicly a clock. That ticks at QueryPerformanceFrequency number of times a second. It will loop eventually.
QueryPerformanceCounter returns the number of "ticks" since the computer was rebooted. QueryPerformanceFrequency returns the number of "ticks" in a second.

To measure the duration of a frame (or anything else), you call QueryPerformanceCounter at the beginning of the frame and save the value so that you can compare it to the value returned at the end of the frame (actually, comparing it to the value beginning of the next frame is better).

Suppose at the beginning of the frame, QPC returns 3579545 and at the end of the frame it returns 3591310. Then you know the duration of the frame is 11765 "ticks". If you call QueryPerformanceFrequency and it returns 1000000 (one million ticks per second), then you know that the duration of the frame is 11765 / 1000000 or 11.765 ms. The frame rate is calculated as 1/duration, so if your frame's duration is 11.765 ms, then the frame rate is 85 fps.

Now, you wrote that QPC returned 3579545, but I believe you meant to write that QueryPerformanceFrequency returned 3579545. 3.579545 MHz is a frequency used by NTSC, so it would not be surprising to see it as QPC's frequency. A frequency of 3579545 means that on your computer, there are 3579545 QPC "ticks" every second.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Ok... from all of the information here I think I'm understanding it now.

Thanks a ton!!
Quote:Original post by sofakng
Quote:Original post by JohnBolton
QueryPerformanceCounter returns the number of "ticks" since the computer was rebooted.

That was exactly what I was looking for. So the timer does not reset until the computer reboots and thus, you would never have a duplicate number (until the computer rebooted).

Thanks for the excellent information!


That's not exactly true. Eventually, the ticks will wrap around to zero if you leave your computer on for a long time. But for all practical purposes that doesn't matter. You would never see the same number from one frame to the next (unless you have a reeeeaaaaalllllyyyyyy low frame rate). :)
By "reeeeaaaaalllllyyyyyy low frame rate" you mean it's rendering so quickly that according to the counter, it didn't even take 1/QPF to render it?

In the article High Resolution Timing in Games it has the following code:
   do   {      // get the time till its not equal to start frame time, it	  // should never loop at the rate of this timer, but if it	  // does then it will cap to the frame rate to the rate of	  // this timer which is 1193180 Hz      frameend=ftime();  // get end of frame time   } while(frameend==framestart);

This is basically doing what I talked about above? (eg. the frame rendered in 0 time [QPC returned the same value from the previous frame])
Actually, by "r***y low frame rate" I meant slow, not fast. If you had a frame that took so long to render that the counter wrapped back around, you would have one heck of a serious problem (that has nothing to do with the counter).

But, to answer your real question, it won't hurt to have a loop like you've shown, but the loop would probably never execute since it is very unlikely that a frame (even an empty one) would take less than 1/QPF.
Quote:Original post by Dave Hunt
Eventually, the ticks will wrap around to zero if you leave your computer on for a long time. But for all practical purposes that doesn't matter.

But, I thought the counter wouldn't wrap unless you left your computer on for a very long time?

Quote:Original post by sofakng
But, I thought the counter wouldn't wrap unless you left your computer on for a very long time?
It won't wrap around very often at least, but I don't think Windows makes any guarantees about the initial value. Imagine what would happen if the counter started right before a wraparound point at startup.

However wrapping shouldn't be a problem as long as you don't measure your performance in frames per week. Just be careful not to convert or modify the two raw counter values before making the subtraction to find out the elapsed time.

Using modular arithmetic to avoid timing overflow problems

This topic is closed to new replies.

Advertisement