Depending on your goals, using a deadline sleep (sleep_until in C++ parlance: https://en.cppreference.com/w/cpp/thread/sleep_until) rather than a duration sleep (sleep_for) is beneficialReply
Sleep and functions like it should be [almost] banned...
They choose a time that computation happens. But computation should instead be done as soon as possible, and the output delayed to the necessary time.
For example, in an animation, you don't need to wake up the CPU every 16ms to compute the next frame. You should instead just compute all the frames and send it off to the GPU to display in order and with the right timings.Reply
It's probably for the sake of an example, but writing a game/render loop with Sleep is a bad idea, perhaps even on a realtime OS. What you should be doing is to render the frame that's meant for the current time. This way slowdowns, hiccups, boosts don't alter the speed of animations, and you can regulate how frequent you render regardless of the timer precision.Reply
Linux and MinGW can just use nanosleep().
As for Windows, use CreateWaitableTimerEx, with a CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag.Reply
You could also drive this using an audio queue which uses hardware to generate the timer events.Reply
When I was an intern at ON Semi, I worked on a testbed that was designed to stress power mosfets with extremely time-accurate pulses of current. The prototype was using an Arduino microcontroller, and I noticed that when I passed small values to delayMicroseconds(), it was just not accurate at all. After a lot of digging, it turned out that they used a small inline assembly loop to count clock cycles, but they had miscounted the number of clock cycles required by the setup. When you're talking about 2-3us with an 8MHz clock, even half a dozen clock cycles will make a big difference!Reply
Looks like a good way to drift from the clock and eventually skip frames.Reply
Not 100% sure the article doesn't cover this, but if you want a constant rate of wakeups over time (not a precise duration of each sleep call), it's important to schedule your next sleep 1 period after your most recent intended wakeup time (in absolute time), not 1 period after the call to the sleep function (in relative time), to ensure that the time spent after sleep() returns before you call sleep() again doesn't accumulate with every sleep iteration and cause you to fall behind in real time.Reply
It's rarely a good idea to implement spin locks as an empty while() loop. Processors have a special instruction for the spinning, _mm_pause()Reply
On windows you can get 1ms accuracy out of the built in Sleep() function by calling timeBeginPeriod It sets the resolution of timers in that process to the specified ms value. I've used this + spinning to make high res sleep before and it works well.Reply
This seems like an anti-pattern.
I usually tell people that sleeps only belong in one place in their code and they should make linters complain if it pops up anywhere else. The place is the method they call to poll. And even then it's better to wait for something than poll to see if we're ready.
This, though, seems to be trying to sleep to slow down frame rate. What the? Maybe it's intended as some way to make all users' experiences suck equally even if they have fast boxes. Maybe. And depending on the actual scenario maybe it makes sense to handle this with a "better" sleep.
The problem as stated is not a solved problem because it's not generally anything anyone would want to do.
In fact, people might have left this intentionally hard to do to discourage its use.Reply