Skip to main content
gamedev.net
🔒 Locked

Inconsistent Sleep() duration

Started by spiralmonkey 10 replies 1.6k views
Original Post
spiralmonkey
spiralmonkey
I'm trying to smooth my frame-rate using the Sleep() command to eat up time between redraws but i've noticed some peculiar behavior. Sometimes it has a minimum Sleep cycle of 10 milliseconds - i do a Sleep(1) and it doesn't return until 10 milliseconds later. Other times i've used it and it returns in the 'as-advertised' 1 millisecond. Has anyone experienced this before, or have any idea why this might be happening? thanks, alan
Alan Kapler, Developer of Dream Aquarium www.dreamaquarium.comhref=http://www.spiralmonkey.com>www.spiralmonkey.com
Oluseyi
Oluseyi
Sleep is guaranteed to suspend your process for a minimum of the specified interval. It's free to do quite a bit more, depending on the load on the process scheduler.

It's in the documentation, too.
Morpheus011
Morpheus011
sleep is definitely not the way you should be doing this. Sleep() will actually force windows to perform a context switch (multithreading stuff, feel free to ask for more detail). Oluseyi is exactly right too, it's only garaunteed to pause at least the time you specify, nothing else. I would recommend looking into using time based rendering or using a frame delimiter of some sort. Google either of those phrases and I'm sure you'll find loads of goodies :) Good luck, PM me if you want more specifics on context switching or frame delimiters, etc.
spiralmonkey
spiralmonkey
Thanks for clearing that up about the Sleep() command. i made a bad assumption.
I should point out that my application is a 3D screensaver, and one thing i'm trying hard to do is make it very easy on the CPU. Is there any way other than using Sleep() to give away CPU cycles to other processes, and still have accurate timing for my playback?

right now i am empirically measuring the 'coarseness' of the Sleep() command and using Sleep() to get close to my desired timing, then using a more accurate time-wasting loop to eat up the rest.

And a little off topic, is there any way find out what the current vertical refresh position of the screen is???

you can check out my current progress at www.dreamaquarium.com
Alan Kapler, Developer of Dream Aquarium www.dreamaquarium.comhref=http://www.spiralmonkey.com>www.spiralmonkey.com
Drew_Benton
Drew_Benton
If you want to be able to set the resolution of the Sleep function you can use the ideas presented in this post. That method was shown by someone else as well, but that's the first occurance I can find of it. Click here for a list of all those possibles. Not sure if it'll help you, but it's do-able.
Sneftel
Sneftel
Setting your app to a higher priority may go a long way towards making Sleep() lose less time, depending on your version of Windows.
spiralmonkey
spiralmonkey
Drew_Benton's link held an awesome nugget which i'll pass on to anyone experiencing the same problem.

a full description of Ryan Geiss's timing experiments can be found here:
http://www.geisswerks.com/ryan/FAQS/timing.html

to boil it down, the timeBeginPeriod() function can be used to set the resolution of the Sleep() command for your current process. doing a timeBeginPeriod(1) makes my Sleep(1) last 1 millisecond as desired. This is what i needed. However, i must add that adding this causes my program to use a fair bit more CPU than the coarse 10 ms Sleep resolution, for some reason. However it's better than the time-wasting loop.

thank-you all very much for the help!

[Edited by - spiralmonkey on October 18, 2005 1:44:25 AM]
Alan Kapler, Developer of Dream Aquarium www.dreamaquarium.comhref=http://www.spiralmonkey.com>www.spiralmonkey.com
Spoonbender
Spoonbender
Do you really need more precision than ~10ms for a screensaver?
Kitt3n
Kitt3n
>Sleep() will actually force windows to perform a context switch
Sleep does not necessarily force a context switch.

From the MSDN:
"A value of zero causes the thread to relinquish the remainder of its
time slice to any other thread of equal priority that is ready to run.
If there are no other threads of equal priority ready to run, the
function returns immediately, and the thread continues execution."

I usually have a sleep(0) (so if there are other programs, they also
get some time) and by putting the priority of my app down one level
if it gets put to the background.

visit my website at www.kalmiya.com
jpetrie
jpetrie
This is an interesting blog post discussing some of the pitfalls of the Sleep() function.
Oluseyi
Oluseyi
Quote:
Original post by jpetrie
This is an interesting blog post discussing some of the pitfalls of the Sleep() function.

Note that most of those comments are not pertinent to real-time work.
Spoonbender
Spoonbender
Quote:
Original post by Kitt3n
I usually have a sleep(0) (so if there are other programs, they also
get some time) and by putting the priority of my app down one level
if it gets put to the background.


What, are you programming for Windows 3.1? (Of course, if you're programming something other than a game, ignore this rant)

Other programs do get time, with or without sleep(0).
What you're doing is cutting into *your* share of the CPU and giving that away. You are not "allowing other processes to get some cpu time", because Windows already offers them as much time as your app does (assuming priorities are equal).

Windows splits the available time between all running processes. The key here is "Windows splits..." Windows does this, and enforces it 100% alone. Nothing you can do (short of setting your app to realtime priority, which is evil anyway), can possibly allow you to starve another process of CPU time.

When an app uses 99% CPU, it's not because it's demanding 99%, it's just because it takes everything it is offered by Windows.
So, why does Windows offer one app 99% CPU? Because no one else wants it. Take a look at your computer when you're not running a game. Usually, 99% of the cpu time is spent in the Idle process, which does nothing. (hence the name).
All "normal" processes take the bit of CPU time they need, then yield. So Windows ends up with a pool of 99% CPU time, it tries to offer to anyone who'll take it. And there is no harm in your app taking advantage of that. You're not starving out other processes, you're just grabbing the CPU time that'd be wasted otherwise.

But yeah, if you're making an app that doesn't actually need much CPU time (Typically event-driven, and only redraws its window when it needs to. Which means practically every non-game application), then it's only polite to yield the CPU when you have nothing left to do. But what you should *not* do is yield it when you have work left, out of a misunderstood concern that you're starving other processes. Because you're not.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.