Game Loop - Free CPU

Started by
32 comments, last by CrazyCdn 16 years, 11 months ago
Hello, Most good game loop article I read give those advices : - Consume 100% of the CPU : while(!quit){...} - Separate Rendering from Logic - Update Logic at lower frequency (1/30) - Update Rendering at higher frequency (1/60) - Interpolate Rendering for example : http://www.gaffer.org/game-physics/fix-your-timestep/ http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=63823 Seems good to me, expect the "Consume 100% CPU" (ok for console, not for PC) If you launch Warcraft3 or World Of Warcraft, your CPU will not be 100% busy. On my computer (pentium M 1.7 GHZ) Warcraft3 only consume 25% of the CPU, and the framerate is allways at 60 fps. I'm wondering what type of game loop Blizzard is using. - Do they sleep in the game loop ? Sleep doesnt seem reliable enough... - Do they use windows timer ? [Edited by - noooooon on May 5, 2007 10:12:01 PM]
Advertisement
Quote:Original post by noooooon
Warcraft3 only consume 25% of the CPU, and the framerate is allways at 60 fps.


Emphasis mine. If it's always at 60, then you've got Vertical Sync on, which reduces the frame rate to match the refresh rate of your monitor. It decreases tearing, and is a Good Thing. Since it's reducing the frame rate, you're just idling for a bit, hence the lower CPU usage. So this (almost certainly) has nothing to do with Blizzard's game loop (vertical sync is handled by the graphics drive).

There's nothing wrong with using 100% of the CPU. People rarely do too much else while they are gaming. Maybe a bit of IM or something, but that's about it. Using the whole CPU is fine for games.
IMHO use all the CPU you can, and more than likely you will unless you want alot of overhead slowing the program down. I wouldn't worry CPU usage and worry more about RAM usage.
-----------------------------------------------The ZoloProject
I'd offer the advice of accepting the "WM_FOCUS" message, so that you know when your program is in focus.
While they are looking at your game, who cares if it hogs all the cpu. But if they have to alt-tab away from
it, you should play nice and pause your game loop. (or give an option to, kinda how TheSims has the option
"sims in background" to toggle if it pauses on alt-tab or not)
I had the exact same problem, and I posted the same thread "What loop do commercial apps use, so the CPU won't jump to 100. I was using D3D, I don't know if you are, but Ill try to help anyways. What I noticed is that when I started the game and the window opened the CPU shot up to 100, but then if I resized the window, CPU would drop to about 20% and stay there.
Just in case heres my thread, its pretty long since there was an argument that games are supposed to use 100.
http://www.gamedev.net/community/forums/topic.asp?topic_id=433940

At the end what I realized is that it was the two calls to antialiase that seemed to be slowing everything down, I removed them and everything ran fine at 20-30% CPU.

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

Quote:Original post by Ezbez
Emphasis mine. If it's always at 60, then you've got Vertical Sync on


No it's off. Actually its not allways excatly at 60 (its more between 50 and 60). If I use a higher resolution I can have 45 fps (which is by the way enough for warcraft3)

Quote:Original post by Ezbez
There's nothing wrong with using 100% of the CPU.


I disagree for 2 reasons :
- Today games can be played in window mode, with a bunch of application aside (like MMOs for example)
- I find it silly to use 100% of the CPU if you don't need it. With a standard game loop the program is skipping a lot of frame only to calculate if he needs to render one.

Lets take an example :
- fixed framerate : 60 fps - 16ms (for both update and render)
- update time consuming : 2ms
- rendering time consuming : 5ms

 0ms : Update begin 2ms : Update end      : Render begin 5ms : Render end     : Timer operations : do we need to reloop = FALSE     : Timer operations : do we need to reloop = FALSE     : Timer operations : do we need to reloop = FALSE     : ...     : ...16ms : Timer operations : do we need to reloop = TRUE     : Reloop

Better the CPU, the more it will loop for nothing between 5ms and 16ms because Timer operation are not expensive (comparing to rendering).
Wouldn't it be better if we could free the CPU bewteen the 5ms and 16ms ?

Quote:Original post by Ezbez
So this (almost certainly) has nothing to do with Blizzard's game loop


Blizzard use the same engine for warcraft3 and his map editor. The editor is more like a common a window application, but it contains a window with the game rendered in real time. When you place an entity, it has his animation played, her visual FX are updated and so one. Only the controls and the gameplay are not actived in the editor. This application doesn't take 100% of the CPU (only 10%). It would be stupid for an editor dont you think ?

So i'm pretty sure they use the same kind of game loop for both game and editor.
ok so according to the folowing post, a solution is just to do a Sleep(1) in the loop to "make task scheduler happy" :
http://www.gamedev.net/community/forums/topic.asp?topic_id=433496

So now here is what happends :

0ms : Update begin2ms : Update end     : Render begin5ms : Render end    : Timer operations + Sleep(1) : Free CPU for other process    : Timer operations + Sleep(1) : Free CPU for other process    : Timer operations + Sleep(1) : Free CPU for other process    : ...    : ...16ms : Reloop


I tought Sleep was not reliable, but seems to work.
Quote:Original post by noooooon
So i'm pretty sure they use the same kind of game loop for both game and editor.


false logic.
For starters they are two different programs, which means two different main loops right off the bat, the game one could work one way (and probably will) were as the editor app would be designed so it's main loop didn't totally chew the CPU time up.

Quote:Original post by noooooon
I disagree for 2 reasons :
- Today games can be played in window mode, with a bunch of application aside (like MMOs for example)
In that case, your game and the other applications would share the CPU. Your game would yield if the other application would want CPU-time and vice versa. (This might need a Sleep(0) in your game loop).
Quote:Original post by noooooon
- I find it silly to use 100% of the CPU if you don't need it. With a standard game loop the program is skipping a lot of frame only to calculate if he needs to render one.
But when would you not need it? You might argue that it is unnecessary to render faster than the monitor refresh rate. In that case, turn VSync on (or better yet, let the user choose).
Quote:Original post by noooooon
Wouldn't it be better if we could free the CPU bewteen the 5ms and 16ms?
In case you want to limit frame rates, yes it would be: either use VSync (so that your game loop is limited at the monitors refresh rate), or Sleep().
Quote:Original post by noooooon
I tought Sleep was not reliable, but seems to work.
The reason you could think of Sleep as unreliable is that your process is not guaranteed to wake up exactly after the time you specified in the Sleep command. Your process will sleep for at least that amount of time. Sleep(0) is a special case, where your process will give up it's remaining time of its time slice for another process.
"Sleep loops" aren't automatically unreliable. If it is just a naive sleep loop, attempting to rely on Sleep() to actually time each iteration of the loop, then yes, it will work out badly in many cases. However, there are some loops that work very well at 100%, but it is also very easy to add in a Sleep() call into the loop, and the loop will still work perfectly well, while CPU usage is greatly reduced (depending on the CPU intensity of the game, of course). This is because the loop uses other techniques to manage timing and such, but still sleeps to be nice to the system. The key is to make the loop inherently compensate for iterations that take less or more time than is intended.

If an iteration took too long, then the following iterations need to be done more quickly until it is caught up to where it should be. In many cases, this involves running game-logic stuff at full speed as many times as necessary to catch up, without rendering at all. If the previous iteration lasted as long as 3 iterations should last, then the next time through, run the game-logic three times (such as managing game objects, running physics, et cetera), and only render after that point. If rendering is the problem, then the game will continue running internally at the same speed, but your framerate will be lower.

If an iteration went by too quickly, well then that just means that you can sleep longer. If you still didn't sleep long enough, then just skip everything else for that time, and sleep again. You can render if you want, or perhaps handle input, in order to maintain a high feel of responsiveness, but it likely doesn't need to be done for many games.

If you get your loop done well, then you can have each component of your game running at a potentially different frequency, as well as each component choosing if it can skip missed iterations if it likes. To get repeatable reliable physics, then have it run at a fixed frequency of 45 Hz, for example, and not allow skipped iterations. Run input at 120 Hz for quicker response, perhaps, but allow it to skip iterations. If you missed a few iterations due to a hiccup, there's no reason to check input three times in a row as quickly as possible; just check it once. Allow an option to let graphics run at the same frequency as input, as fast as possible, or at the vertical retrace frequency. Again, don't bother rendering frames that were missed, there's no use. If there's networking, perhaps let it run at yet another frequency. If you get things set up well, you might manage to obtain a good number of the benefits of multithreading while still using a single threaded model.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

This topic is closed to new replies.

Advertisement