Sign in to follow this  
graveyard filla

Sleeping() away the time left over from a frame???

Recommended Posts

hi, i've been working on my 2d map editor lately, and i have the frame-rate locked. the FR is locked at 30 FPS. anyway, i find the app is a hog of the CPU (like my game also and every other indi game i've played). now, since it's locked at 30 FPS, at the end of a frame, i wait till 1/30th of a second passes before moving to the next frame using an empty while(); loop. this works fine, but it seems like such a waste of precious CPU power. now, how bad would it be for my to Sleep() for the excess time left over from a frame, instead of just waiting it out in an empty loop? this *should* give the same effect, only it will free up the CPU to do other things. ive already implemented it in the map editor, and it works great! usually its 0-1% CPU usage instead of around 50%. my only concern is the inaccuries with Sleep (actually, i use SDL_Delay, which on windows is the same thing i believe). now, if it is very in accurate, couldnt i perhaps Sleep off half the time that's left over, and then any remaining time thats left after the sleep would be finished off in an empty while loop? would this avoid any inacuracy problems? i know it wont free up the CPU as much as i'd like, but its better then nothing. i know theres people who know about this stuff and have experiance, so please enlighten me. thanks.

Share this post


Link to post
Share on other sites
Spinlocks are wasteful. Yielding is a good idea - unless you do have some actual processing to do.

However -
Does it really matter if your game "hogs the CPU"?
Have you checked whether it made your system less responsive?
Or do you just want your computer to remain idle?

Share this post


Link to post
Share on other sites
Try putting Sleep(0) in the while loop. This causes the thread to give up the remainder of its time slice. Basically, it'll just say "nope, i've got nothing interesting to do" until it's time for the next frame. You should still get accurate timing that way.

Share this post


Link to post
Share on other sites
@Fruny

Spinlocks? what is that exactly, sleeping off remaining time or while()'ing off remaining time?

Yeilding, how does that work exactly?

about "do i really need it?". well, i knew someone would say that [smile]. im not sure, but i notice that when the app is running, and say Trillian is open, when a Trillian window pops up, it seems as if the Trillian window can't "pop through" the app as fast. i've noticed that it pop's through much more easily when the CPU usage for my app is only 0 or 1%. so yeah, id like to do this if its possible and not too much trouble.

@uavfun

i know that trick, but it doesnt seem to work that good.

thanks guys for the help.

Share this post


Link to post
Share on other sites
That should work, with some caveats. I'm assuming Windows here (because otherwise you'd be talking about usleep() :-)

What you're doing is trying to make a time-sharing consumer OS do what's basically a real-time task. This isn't super easy, but can be done with some success.

Sleep()-ing is very jittery on DOS-based Windows. At best, you get +/- 20 ms precision, which is too low to use for interactive applications that want smooth frame rate. So detect Win98/ME and turn off sleeping, or have a check-box to turn it off.

Sleep() signals to the OS that you have nothing better to do, which will cause SpeedStep CPUs to slow down. Unfortunately, this means that your main loop will run at the slower speed, so you'll be falling behind, and won't be sleeping. Finally, the OS will notice you're not sleeping, and up the CPU speed. Then you'll start sleeping again, and the OS turns on SpeedStep... Detect SpeedStep and turn off sleeping, or have a check-box to turn it off.

Sleep() may wake up later than you tell it to (as I said, jitter), although it's pretty good on NT-based Windows (such as Windows XP). Thus, I'd set a wake-up point about 2 milliseconds before when I need to swap frames, and just accept that I'll be spinning for 2 milliseconds each frame (minus wake-up delay). If there's less than 2 ms left before flipping, don't sleep at all. You may find that wake-up precision is better if you raise the priority class of your application and the priority of your thread.

Sleep() does not wake up if there are windows events waiting for your window. For better interactivity, you may want to create an event that you never set, and then call WaitForSingleObjectEx() with a time-out. This is known as an "alertable" sleep, and will wake you up if there are suddenly events delivered to your application (such as mouse movement). You could even run your Windows message pump that way: sleep and/or handle messages until such time as it's time to flip; then flip; then handle any remaining Windows messages before you go on to simulate and render the next frame.

Good luck!

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