Jump to content

View more

Image of the Day

Adding some finishing touches...
Follow us for more
#screenshotsaturday #indiedev... by #MakeGoodGames https://t.co/Otbwywbm3a
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.


Sign up now

Game Loop - Free CPU

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
33 replies to this topic

#1 noooooon   Members   

122
Like
0Likes
Like

Posted 29 April 2007 - 12:03 AM

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]

#2 Ezbez   Members   

1164
Like
0Likes
Like

Posted 29 April 2007 - 12:19 AM

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.


#3 speedie   Members   

140
Like
0Likes
Like

Posted 29 April 2007 - 05:55 AM

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.

#4 KulSeran   Members   

3247
Like
0Likes
Like

Posted 29 April 2007 - 08:37 AM

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)


#5 VanillaSnake   Members   

174
Like
0Likes
Like

Posted 29 April 2007 - 11:23 AM

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

 

Time flies like an arrow; fruit flies like a banana. - Old Wise Eastern tribesman saying


#6 noooooon   Members   

122
Like
0Likes
Like

Posted 29 April 2007 - 11:35 AM

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.

#7 noooooon   Members   

122
Like
0Likes
Like

Posted 29 April 2007 - 11:46 AM

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.

#8 phantom   Members   

11238
Like
0Likes
Like

Posted 29 April 2007 - 11:48 AM

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.



#9 DaBono   Members   

1491
Like
0Likes
Like

Posted 29 April 2007 - 11:48 AM

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.

#10 Andy Gainey   Members   

3452
Like
0Likes
Like

Posted 29 April 2007 - 11:58 AM

"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.

#11 Jimmy Valavanis   Members   

229
Like
0Likes
Like

Posted 29 April 2007 - 08:54 PM

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.

#12 jpab   Members   

881
Like
0Likes
Like

Posted 29 April 2007 - 09:41 PM

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

#13 DaBono   Members   

1491
Like
0Likes
Like

Posted 29 April 2007 - 09:52 PM

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.



#14 haemonculus   Members   

126
Like
0Likes
Like

Posted 29 April 2007 - 11:01 PM

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

#15 noooooon   Members   

122
Like
0Likes
Like

Posted 30 April 2007 - 05:46 AM

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.





#16 nonameasdf   Members   

792
Like
0Likes
Like

Posted 01 May 2007 - 06:50 AM

Agony, I've never thought of doing that. Seems like a good idea. Thanks for sharing!

#17 Extrarius   Members   

1412
Like
0Likes
Like

Posted 01 May 2007 - 11:03 AM

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.

#18 BradP   Members   

133
Like
0Likes
Like

Posted 02 May 2007 - 09:42 AM

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. :)

#19 gardin   Members   

122
Like
0Likes
Like

Posted 02 May 2007 - 09:39 PM

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?

#20 _moagstar_   Members   

465
Like
0Likes
Like

Posted 02 May 2007 - 10:19 PM

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?




Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.