How much CPU usage should just an empty game loop have

Started by
22 comments, last by freeworld 11 years, 5 months ago
How much CPU usage should show when an engine is running an empty game loop? An (almost) infinite loop like the game loop eats up more CPU time than other programs, but how much is too much? Should I be adding sleep calls to it and limiting updates to 60hz? Because it's showing 60% CPU usage in the task manager as opposed to 10-14% when the game isn't running.
Advertisement
Your CPU usage should be around 0-1%.

Don't use sleep calls. Instead, calculate how much time has elapsed and update when you've passed that time span.
If you want to update 60 times a second, then there are 1000ms in a second. So, the time span to process a frame should be 1000/60 = 16.66666666666667 ms
When your game loop starts, record the time. Your loop processing will complete long before 16.66ms has elapsed, but as you add more logic, the time it takes will increase. So, you want to make sure that before starting the next frame, the current time >= last frame time + 16.6666ms
this would lock your FPS at a max of 60. But, when you're moving stuff around in your game, don't move it a fixed amount each frame. Move it based on how much time has elapsed between frames. That way, if your actual frame rate increases or decreases, your game state model is still running according to real time.

If you process your next frame when a set time span has elapsed, you should get about 0-1% cpu usage since it takes next to no time to process your update loop.
I think he meant to use the sleep function to wait until its time for the next frame?

o3o


I think he meant to use the sleep function to wait until its time for the next frame?
Yeah. Or Sleep(0) to give up the remainder of my timeslice.
It seems like using sleep() is ok, but you should measure the time it takes to process your updates, so that if they take long, you need to sleep less and if they dont take much time you can sleep longer to keep a consistent FPS.

simplified version:

Timer
while running do
{
Timer.start()
UpdateStuff()
Timer.stop()
sleep(FrameLenght - min(FrameLenght,Timer.GetTimeElapsed())) //min() to not go negative, FrameLenght is 1 second / FPS converted to whatever sleep takes in (ms?)
}

You might want to have it measure longer periods of time in case the loop and timing itself takes a ridiculous amount of time for no reason (i dont think thats needed but i could be wrong) or catch up if its laggy for some time by doing extra updates after.

o3o

Be careful when using Win32's Sleep. The call might return instantly or sleep for up to ~15 ms when calling Sleep(n), where 0 <= n <= 15. This happens because the default tick resolution is (1/64) s = 15.625 ms, which can be altered (only for the entire system!) using timeBeginPeriod/timeEndPeriod.
So you might want to consider other alternatives when you need to wait for less than 15 ms.
If you're writing a realtime game and want smooth animation, avoid limiting the framerate with Sleep. Use vertical sync in your graphics API instead, which will limit your game to 60 fps if your screen is set to 60 Hz. Usually DirectX and OpenGL nowadays handle vertical sync by sleeping to avoid high CPU usage if your game processing completes with time to spare before screen refresh. Internally they will use some system-level sleep that is made to wake in time for the swap, whereas an application level sleep can cause tearing and stuttering in your animation, as nife87 explained, and you probably want vertical sync anyway to make everything look smooth even if you don't care about sleep.

For casual games and window mode Sleep might be a good choice.

If you're writing a realtime game and want smooth animation, avoid limiting the framerate with Sleep. Use vertical sync in your graphics API instead, which will limit your game to 60 fps if your screen is set to 60 Hz. Usually DirectX and OpenGL nowadays handle vertical sync by sleeping to avoid high CPU usage if your game processing completes with time to spare before screen refresh. Internally they will use some system-level sleep that is made to wake in time for the swap, whereas an application level sleep can cause tearing and stuttering in your animation, as nife87 explained, and you probably want vertical sync anyway to make everything look smooth even if you don't care about sleep.

For casual games and window mode Sleep might be a good choice.


Yeah I'll have vsync setup for sure. I'm talking about the game loop though not the rendering loop.
Okay. I used an event and WaitForSingleObject to wait for a maximum of 100 ms when the game doesn't have focus. Now when the game doesn't have focus it uses up almost no CPU time at all. When nothing is running except windows I have 10-20% CPU usage. The game loop doing nothing at all (I event commented out every single call to update a subsystem) shows 50-60% CPU usage. So my game loop accounts for about 40-50%. What's weird though is that when the game is running logic it stays at just about exactly 50%. Why would this be? I'm doing some more work, but my CPU usage doesn't end up fluctuating as high. Could it just be a fluke and the OS is doing stuff behind the scenes? Or could it be because I send tasks off to other cores with a thread pool?

Okay. I used an event and WaitForSingleObject to wait for a maximum of 100 ms when the game doesn't have focus. Now when the game doesn't have focus it uses up almost no CPU time at all. When nothing is running except windows I have 10-20% CPU usage. The game loop doing nothing at all (I event commented out every single call to update a subsystem) shows 50-60% CPU usage. So my game loop accounts for about 40-50%. What's weird though is that when the game is running logic it stays at just about exactly 50%. Why would this be? I'm doing some more work, but my CPU usage doesn't end up fluctuating as high. Could it just be a fluke and the OS is doing stuff behind the scenes? Or could it be because I send tasks off to other cores with a thread pool?


What you've got is something similar to a "spin loop", which is commonly used in multithreading spin and wait until a resource becomes available again. Except, it's really just an infinite loop. It'll run as fast as it can, provided the operating system gives it all the CPU resources it can.

I'm guessing that your computer has a processor with two cores. The spin loop is running in a thread on one of those cores and maxing it out at 100%, and because you've got two cores, one of which is 100% and the other at 0%, the average CPU usage is almost exactly 50% (with noise from other processes/threads causing fluxuations). If you're using task manager to measure CPU usage, you can view each core independently: View -> CPU History -> One Graph per CPU

You'll want your game loop to return the CPU to the OS until a desired time span has elapsed (which I mentioned above). You can use the Sleep function and probably get away with it without having any issues.

This topic is closed to new replies.

Advertisement