Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange 'Sleep' behaviour between systems

Tags:

c++

timing

winapi

I have a program that uses Sleep Win32 API call to make a thread wait for a specific amount of time.
In short, it simulates a camera by sending images prefetched in memory. I'm using Sleep to simulate the frame rate -- Sleep(1000 / fps)

This works fine in my development system (Intel i5 (1st gen), Win7 64), but when I run it on another system (Intel i7-2600 - SandyBridge), the sleep times are totally different and inaccurate.

For example, Sleep(16) sleeps for around 32ms
Sleep(3) sleeps for 16ms

In the past I thought there was a minimum sleep time in windows of 15ms but I do not get that limitation on my dev system.

Any Ideas?

In addition, is there a better way to achieve the frame rate of my simulator?

like image 266
Itsik Avatar asked Jan 02 '12 09:01

Itsik


People also ask

What is a Sexomnia disorder?

Sexsomnia, also known as sleep sex, is a type of sleep disorder known as a parasomnia. Parasomnias refer to unusual sensations and behaviors, such as sleepwalking, that people may experience or exhibit while asleep, falling asleep, or waking up.

What is transient parasomnia?

Parasomnias are undesirable sleep-related events that may occur during sleep or during the transition into sleep or out of sleep. They include abnormal behaviors (e.g., sleepwalking) and dreams (e.g., nightmares). Parasomnias may be transient and have no significant consequences on the patient's sleep health.

What causes thrashing around in sleep?

Rapid eye movement (REM) sleep behavior disorder is a sleep disorder in which you physically act out vivid, often unpleasant dreams with vocal sounds and sudden, often violent arm and leg movements during REM sleep — sometimes called dream-enacting behavior.


2 Answers

The sleep function guarantees that you will sleep for at least the amount specified in the call. It causes the thread to suspend, allowing switches to other threads (governed by thread priorities) at the leisure of the scheduler. In other words, the sleeping thread is not guaranteed to run immediately after the specified time has elapsed, so using sleep for accurate timing should be avoided in the general case.

There are ways to achieve more accurate sleeping on Windows however. You can call timeGetDevCaps to determine the minimum supported timer resolution, and then call timeBeginPeriod once early in your application to set the timer resolution to its minimum. Be sure to call timeEndPeriod before your application exits.

For more information, see the Sleep function on MSDN.

like image 133
Håvard S Avatar answered Oct 05 '22 05:10

Håvard S


Instead of relying on inccurate sleep behaviour or platform specific timer functions (which may work well, I don't know), you could structure this like a game loop.

Inside the loop you call a function to give you the current time. You figure out how long has elapsed since you drew the last frame and and decide when to render the next frame yourself exactly at the right time. During development you should measure the actual number of frames per second and display it.

With this approach, tt is easier to make your code cross platform and more accurate. Also your loop is in control rather than structuring your code as timer callbacks which you might also prefer.

The disadvantage is that a "busy wait" loop means your process will be using the CPU all the time unnecessarilly. To mitigate that you can yield the CPU in your loop by explicitly pumping user interface events in some way or perhaps using a shorter sleep :-).

If you want to learn more about this approach then start googling for material on game loops.

Here are some essential links:

http://www.koonsolo.com/news/dewitters-gameloop/

http://gafferongames.com/game-physics/fix-your-timestep/

And a discussion on SO:

https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step

like image 35
ScrollerBlaster Avatar answered Oct 05 '22 05:10

ScrollerBlaster