# Frame rate timing

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

## Recommended Posts

I have a few questions about how to do frame rate timing in games.

Here is some pseudocode for my logic game loop:
 baseTime = GET_TIME(); lagTime = 0; FRAME_TIME_MS = (1000 / 60); MAX_LAG_MS = 500; frames = 0; while (!done) { frameTime = baseTime + lagTime + frames * FRAME_TIME_MS; targetTime = frameTime + FRAME_TIME_MS; RCV_GRAPHICS_THREAD_MESSAGES(); if (no graphics messages have been received for, say, 15 updates) { // pause so the graphics update queue doesn't keep building up WAIT( ... ); continue; } // run the logic // send relevant updates to graphics thread // push frame commit SEND_RENDER_MSG_TO_GRAPHICS_THREAD(frameTime); // get the time at the end of the frame actualTime = GET_TIME(); if (actualTime < targetTime) // go idle if we have extra time WAIT( targetTime - actualTime ); else if (actualTime - targetTime > MAX_LAG_MS) // if we've lagged too long, add to our allowed lag time so we don't keep building up lagTime += actualTime - (targetTime + MAX_LAG_MS); ++frames; } 
And graphics:
 FRAME_PADDING = 50 while (!done) { RCV_MAIN_THREAD_MESSAGES(); while (more messages) { process message if (msg == RENDER) { if (GET_TIME() > msg.frameTime - FRAME_PADDING) // only render if we're "caught up"; otherwise, drop the frame (means we fell behind, hence low FPS) render(); // alert the main thread that the previous frame has been processed // if the main thread doesn't receive these alerts, it should temporarily freeze so that updates don't build up SEND_MSG_TO_MAIN_THREAD(); } } } 

You'll notice that I'm basing frame timings off of a base (game start) time instead of the previous frame. This seems like it would be more accurate when trying to synchronize things such as audio for example, since the nth frame timing will always be n*FRAME_TIME_MS into the game and does not depend on the frames that came before. If the game freezes, however, this would be an issue, which is why I introduced lagTime, which adjusts the base time frames are calculated from if the game pauses for too long.

Anyway, my here are my questions:
0) Do you see any problems with this approach?

1) What is the best timer to use for the purpose of frame rate timing? I'm running Windows.

2) Obviously since 60fps is 16.6666666666666... ms, I can't represent it exactly, so FRAME_TIME_MS won't be quite right for 60fps. Is this worth worrying about? If so, how is it generally solved?

3) Right now I have WAIT( ... ) in place of a pause when I have extra time left over. What should I use for this? Sleep( ms ) won't work as it's not accurate enough. I could use "spinlock", but that would mean my logic thread is ALWAYS using 100% CPU, and I've seen games that don't seem to do this.

##### Share on other sites
1) AFAIK, the performance timer (QueryPerformanceTimer/Frequency).
2) Don't limit yourself to integer millisecond amounts. I used doubles for time.
3) You can use a spinlock with Sleep(0). Sleep(0) only gives up the rest of your time-slice, instead of waiting for a certain number of ms, which keeps it fairly accurate, but still gives the OS enough time so you don't 100% thrash the CPU.

##### Share on other sites
Thanks, I will give your suggestions a try!
One more thing concerning 1... I've read about QueryPerformanceTimer having some problems, especially on multicore and systems that use Cool'n'Quiet, such as sometimes counting "backwards". Is this an issue I should be concerned about?

##### Share on other sites
why not use nanoseconds or microseconds with a 64-bit timestamp (+ usleep or nanosleep)?

##### Share on other sites

Thanks, I will give your suggestions a try!
One more thing concerning 1... I've read about QueryPerformanceTimer having some problems, especially on multicore and systems that use Cool'n'Quiet, such as sometimes counting "backwards". Is this an issue I should be concerned about?

I've never experienced any problems and I've no idea how much this happens. However, you can set up a control timer to detect sudden jumps in the timer using a lower resolution but more secure timer like GetTickCount (I'm assuming it is, because that's what I do ).

1. 1
2. 2
Rutin
19
3. 3
JoeJ
16
4. 4
5. 5

• 35
• 23
• 13
• 13
• 17
• ### Forum Statistics

• Total Topics
631701
• Total Posts
3001810
×