Sign in to follow this  
noooooon

Game Loop - Free CPU

Recommended Posts

noooooon    122
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]

Share this post


Link to post
Share on other sites
Ezbez    1164
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.

Share this post


Link to post
Share on other sites
speedie    140
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.

Share this post


Link to post
Share on other sites
KulSeran    3267
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)

Share this post


Link to post
Share on other sites
VanillaSnake21    175
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.

Share this post


Link to post
Share on other sites
noooooon    122
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.

Share this post


Link to post
Share on other sites
noooooon    122
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 begin
2ms : Update end
: Render begin
5ms : 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.

Share this post


Link to post
Share on other sites
_the_phantom_    11250
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.

Share this post


Link to post
Share on other sites
DaBono    1496
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.

Share this post


Link to post
Share on other sites
Agony    3452
"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.

Share this post


Link to post
Share on other sites
Consider theese:
Fps can be limited by the vertical sync.
Fps can vary from a computer to another.
AI MUST run the same to all computers!
You can afford to loose some fps. But you can't afford to loose AI circles
because the game behaviour (eg difficulty, movements etc) will vary from
a computer to another.

Share this post


Link to post
Share on other sites
JohnBSmall    881
Just a little note, since everyone is suggesting Sleep(1) or Sleep(0) to give up the rest of the timeslice for other applications, you might want to use the SwitchToThread() function instead, since it's actually designed to give up one timeslice, rather than being designed to wait a particular period in milliseconds.

John B

Share this post


Link to post
Share on other sites
DaBono    1496
Quote:
Original post by JohnBSmall
Just a little note, since everyone is suggesting Sleep(1) or Sleep(0) to give up the rest of the timeslice for other applications, you might want to use the SwitchToThread() function instead, since it's actually designed to give up one timeslice, rather than being designed to wait a particular period in milliseconds.
Being nitpicky: SwitchToThread() gives up one timeslice, while Sleep(0) gives up the remainder of the current timeslice.

Share this post


Link to post
Share on other sites
haemonculus    126
I would like to not use 100% of cpu becaue games on a notebook that don't need to use 100% are only using too much energy.
If the game only uses 30% then the cpu can run at a lower frequency which is much better :)

Currently I'm using a loop which checks if it should render/update/... or if there is time available Sleep(1).. Sleep(0) does no impact for cpu usage :/
I'm not happy with this solution but it's the best I came up with. Well I'm trying to multithread the whole thing and then caring for cpu usage looks like hell to do

Share this post


Link to post
Share on other sites
noooooon    122
Quote:
Original post by phantom
false logic.
For starters they are two different programs, which means two different main loops right off the bat


I said the same "kind" of game loop, not the same one. Both dont use 100% CPU.

Quote:
Original post by phantom
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.


Yes, and that's actually my question. I'm looking for a loop that doens't "totally chew the CPU time up". The war3 game or war3 editor loops would be both fine for me since both dont use 100% CPU.

Quote:
Original post by Jimmy Valavanis
You can afford to loose some fps. But you can't afford to loose AI circles
because the game behaviour (eg difficulty, movements etc) will vary from
a computer to another.


It's not my point. As I said before in the post, I use a constant game update frequency (Physic, AI, ...), separated from the rendering frequency.
I lookd for a way not to freeze the CPU. Sleep(0) or Sleep(1) seems to work, but I thought tey would be a better way to do it.



Share this post


Link to post
Share on other sites
Extrarius    1412
Quote:
Original post by Ezbez
[...]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.[...]
It's easily arguable that it's not a good thing. If frames take 1/59 of a second to render, turning on VSync at 60 Hz will drop your framerate to 30 because the system will wait for the frame to be displayed before starting the next. It can also significantly increase input response latency, which is a Bad Thing. Eliminating tearing isn't bad, but VSync does have negative consequences and games that force it on are annoying to no end.

The rest of your post is entirely correct, however.

As for using window's Sleep() function, it's fine for simple little games but if you use it in anything interesting (meaning any game worth running full screen), I'm going to be upset that I'm getting 60 FPS at most (iirc, sleep typically waits at least 15 ms due to the process-switching quantum unless you pass it 0, in which case your process will likely end up using 100% anyways) instead of the 120+ I should be getting unless you implement it perfectly - I have played a game or two that correctly handles low-fps play, but they are far and few between so it can't be very easy to get it working correctly.

Share this post


Link to post
Share on other sites
BradP    133
It seems like you are building your game as a win32 console application when you want the features of a win32 WINDOWS application. Console applications, being legacy from the DOS days, use up 100% CPU by their very design. Blizzard most definately uses Windows application programming. Most games these days do.

I used to love the simple console days where the main() loops looked so clean, but we're living in a windows world now so I made the reluctant jump to windows programming and actually like it now. It's easy to multithread and DirectX is geared towards it.

When you develop a windows application you have a main loop that will use only as much CPU as it needs to get the job done and check for waiting messsages and process them accordingly. It's important to use PeekMessage and NOT GetMessage to prevent 100% CPU usage in your message loop.

I'll give you an example:

    
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
// Create your window

// Initialize your data

// Now we're ready to receive and process Windows messages.
bool bGotMsg;
MSG msg;
msg.message = WM_NULL;
PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

while( WM_QUIT != msg.message )
{
// Use PeekMessage() so we can use idle time to render the scene.
bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );

if( bGotMsg )
{
// Translate and dispatch the message
if( hAccel == NULL || hWnd == NULL ||
0 == TranslateAccelerator( hWnd, hAccel, &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
else
{
// Render a frame during idle time (no messages are waiting)
}
}

// Clean up

return 0;
}




I highly recommend moving to windows application programming if you want to keep the CPU usage down. Also, let the game loop as often as it wants unless the user chooses a vsync option and even then you'll still process everything but rendering. Good luck!

Edit: If your target platform isn't Windows then forget everything I just said. :)

Share this post


Link to post
Share on other sites
gardin    122
Well, winapi supports callbacks, you can use them to limit your rendering to something like 60 fps. Maybe one idea is to use two threads, one "locked" to around 30 fps, used for updating animations, AI etc etc, and the other spinning as fast as possible, only rendering, this way, the user will get as high fps as possible (i believe this is what most people want), and at the same time will be able to use vsync. You could though lock this thread to around 100fps or something, isnt that what games like counter-strike are doing, from what ive heard, 100fps is max in those games?

Share this post


Link to post
Share on other sites
_moagstar_    465
Quote:
Original post by gardin
Maybe one idea is to use two threads, one "locked" to around 30 fps, used for updating animations, AI etc etc, and the other spinning as fast as possible, only rendering, this way, the user will get as high fps as possible


If you're going to do this I'd say it's better to have the update loop running at the higher resolution, particularly for physics.

Quote:
Original post by Extrarius
Maybe one idea is to use two threads, one "locked" to around 30 fps, used for updating animations, AI etc etc, and the other spinning as fast as possible, only rendering, this way, the user will get as high fps as possible


Is this universally true? Thats a HUGE chunk of frame time, I just did a test and timing each side of Sleep(1) call did actually take ~1ms.

I also read this, and tried using timeBeginPeriod(1) but it made no difference to the timings. Surely there must be a better way of yielding to other threads than Sleep?

Share this post


Link to post
Share on other sites
Ezbez    1164
Quote:
Original post by Extrarius
Quote:
Original post by Ezbez
[...]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.[...]
It's easily arguable that it's not a good thing. If frames take 1/59 of a second to render, turning on VSync at 60 Hz will drop your framerate to 30 because the system will wait for the frame to be displayed before starting the next. It can also significantly increase input response latency, which is a Bad Thing. Eliminating tearing isn't bad, but VSync does have negative consequences and games that force it on are annoying to no end.


I stand correctly. Perhaps "a Good Thing for most users" would be more fitting.

Edit: and it's also very bad for seeing how thing affect performance. "Wow my frame rate just dropped from 60 to 30! I must have done something terribly wrong!" even though it just takes one more millisecond, in reality. Or "Wow, rendering 5 times as many things didn't change my framerate! My engine roxors"

Share this post


Link to post
Share on other sites
Ravuya    135
In general, I think doing the yielding-threads thing is a really good idea; I run a laptop most of the time and it's hard to get involved in a game when the fans are going full blast.

I use the SDL_Delay function from SDL, which (last I checked) uses Sleep on Windows, and usleep on Linux. I'm not sure what it uses on Mac OS X.

Keep in mind that Sleep(n) isn't really going to always take n milliseconds to resolve; depending on the age of your hardware and software, you may be guaranteed to waste at least 20ms of time. In this instance, you may wish to disable this feature. I think the MSDN page for Sleep has a few paragraphs of pitfalls of this function.

Share this post


Link to post
Share on other sites
BradP    133
Assuming WinAPI again, building your loops around a fixed time seems backwards to me. Measure the time delta between loops and apply it to your calculations like physics, AI, rendering, ect? This allows you to create worker threads where you can offset the work on another processor by passing the time delta to an update function. This is how most animation techniques work already and allow the applicaton to run as fast as it wants.

Share this post


Link to post
Share on other sites
Spoonbender    1258
Quote:
Original post by noooooon
Seems good to me, expect the "Consume 100% CPU" (ok for console, not for PC)

Why is this bad? Do we not want the game to run as smoothly as possible? How do you expect it to run as smoothly as possible, if you do not give it as many system resources as possible?

Quote:

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.

You answered it yourself. They cap the framerate, so if a frame takes less than 1/60th to draw, they wait before drawing the next. Result: Framerate at 60, and on fast CPU's, less than 100% CPU usage.

But don't just go into panic mode and assume that "ohnoes, if I use 100% CPU that must be terrible". Because it usually isn't, for two reasons. First, look in task manager while a game isn't running. It's wasting around 99% of the CPU time in the idle process. That is, *no one* are benefiting from it. None of the other running processes want the CPU time, so it's thrown away.
If you allow your game to soak up all available CPU time, it will simply take what would otherwise have been thrown away. Where's the loser in that?

And the second reason: You want your game to run smoothly. That's the #1 priority. Until that is achieved, *don't* call Sleep(). Once it's running smooth, you *may* choose to cap the framerate and stop hogging the CPU. That's what WC3 does, as you mentioned. But it's not something you *have* to do. Most games just render as fast as possible, and use all available CPU time.

Share this post


Link to post
Share on other sites
noooooon    122
Quote:
Original post by BradP
I highly recommend moving to windows application programming if you want to keep the CPU usage down.


Your game loop use 100% CPU. (if less for you then you have multi core or hyperthreading)
So it doesn't solve anything. Your making a "while(true)" game loop, with non blocking calls inside (PeekMessage)


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this