• Advertisement
Sign in to follow this  

Limiting Cpu Usage

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a Monogame-based game that uses variable timestep. The variable timestep causes the game to gobble up all the CPU time it can. The game is a CPU-intensive realtime simulation game. But sometimes it seems the game uses too much CPU, especially when it's on a menu or is paused (even though the player can perform actions while paused) and not much is going on. Some players have noticed this also.

I guess what I want in those instances is to lower the framerate and the number of Update calls the game receives. I can do that quite successfully by inserting the statement Thread.Sleep(50) in the Update method.

But, how can I regulate it so only high performance CPUs are affected, but not the ones which are struggling to keep up. Can I use the IsRunningSlowly flag? Or should I regulate it with the measured framerate?

Edited by captain_crunch

Share this post


Link to post
Share on other sites
Advertisement
The cheap and easy thing is to vsync your renderer and not let your simulation run ahead of that.

Otherwise, you can measure how many frames you've simulated in the past second. If it's above some threshold, say, 60, then use sleep or whatnot to slow you down. Figuring out how many milliseconds to sleep based on your target framerate should just be a little algebra.

Note that you will want to slow down a tiny bit across many frames, rather than a lot on one frame. That'll smooth things out and avoid hitches on high-perf machines.

Share this post


Link to post
Share on other sites

So it sounds like I should slowly increase number of milliseconds slept, and track the FPS at the same time. And if the FPS goes way down, I immediately stop executing Sleep()?

Share this post


Link to post
Share on other sites
You can do that, sure, but by the time FPS rate drops, it's too late. You should try and predict how long your next frame will take, based on the past, and "pad" your frame time accordingly.

Share this post


Link to post
Share on other sites

Ideally you would decouple your logic and render loops so that the logic updates occur in discrete timesteps, while the rendering occurs as fast as it can (usually constrained by vsync).

 

If you're looking for an algorithm to predict framerate, you could maintain a list of the update times for the last x number of updates, and then average those times to predict the future update time. You could even go a step further and track changes to the scene (adding new sprites, deleting old sprites, any other state changes that would change the update time), and then add some adjustment to the predicted time based on those state changes.

 

However, it doesn't make sense that you would experience notably heavier CPU usage while in a menu gamestate. Obviously I have no idea how you handle your logic updates, but maybe the excessive CPU usage you're seeing in those situations is a sign that you should rewire your update logic calls in those states to only update the portions of the game logic that are relevant to the current state?

Share this post


Link to post
Share on other sites

At the beginning of your update:

while time since last update started < 1/max_framerate then sleep(0) end

Sleep(0) would probably not work since the program is single threaded?

"If the value of the millisecondsTimeout argument is zero, the thread relinquishes the remainder of its time slice to any thread of equal priority that is ready to run. If there are no other threads of equal priority that are ready to run, execution of the current thread is not suspended."

Share this post


Link to post
Share on other sites
Generally, there is nothing wrong with a simulation gobbling up 100% CPU as long as there is something to do. The best (both fastest and most energy efficient) way of doing processing is to consume 100% CPU, work off everything that is there to be done, and then sync, doing zero work which puts the CPU into a low-power state (happens very quickly, few hundred cycles, in hardware, on modern processors). Used to be you could just continue sucking up 100% CPU without ever blocking on sync or such, and people would be happy although they couldn't really see the extra frames, but in a time with mobile devices and batteries this is no longer the case (at least not generally). Thus, one will usually by default want to wait on vsync rather than produce as many frames as possible. That still doesn't mean that you shouldn't consume 100% CPU, only just... don't artificially slow down as long as there is something to do. When the game is paused, CPU usage should be zero (or almost zero). There is no work to be done, no updates, so no CPU should be consumed. When you are in the menu ("fullscreen main menu outside game play"), CPU load should naturally drop since there is very little work being done, just responding to some mouse events and drawing a couple of quads. But nothing "special" should be necessary to achieve that. Of course, if you open some kind of config menu (even a fullscreen menu) while the game is running and while the realtime simulation is going on (not paused), the same amount of work is being done as otherwise. It's no surprise that the simulation still consumes CPU, this is a healthy, normal condition. Using sleep is almost always a bad idea. Not only is it unreliable and inaccurate, but it also doesn't do what is intended. You open a big can of worms and add a lot of problems which you really don't want to deal with (over-estimating, over-sleeping, scheduler jitter and other scheduling issues, under Unix there's even under-sleeping, etc). Blocking on vsync works, and it's a proven thing (no pain, still gain!). Blocking on an event/mutex/semaphore/whatever if you have several threads is a proven thing. Sleep is just... trouble ahead.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement