How Accurate Is Thread.Sleep

How accurate is Thread.sleep?

Thread.sleep() is inaccurate. How inaccurate depends on the underlying operating system and its timers and schedulers. I've experienced that garbage collection going on in parallel can lead to excessive sleep.

When doing "real time" simulations you have to correct your main loop for the inaccuracies of sleep. This can be done by calculating the expected time of wake-up and comparing that to the actual time of wake-up and correcting for the difference in the next loop.

If you need better performance, have a look at the Java Real-Time System specification. I haven't used it myself so I can't provide further details.

How accurate is Thread.Sleep(TimeSpan)?

Your thread is sharing CPU Time with other threads. The Sleep will end as soon as it is your turn again and the kernel notices the sleep time has elapsed, so it is not that accurate.

CPU load, process priorities, number of concurrent threads, even from other processes, will have effect upon it.

Thread sleep and precise timing

Timing in modern OSes is never precise, unless you use a language/framework that was explicitly designed for this. You can however work with a reasonable uncertainty in most operation systems. But "reasonable" depends on the problem you are trying to solve.

In Java Thread.sleep is a very basic implementation that is way too overused in my opinion. Java offers these basic threading tools not because they are the best solution, but because they are basic tools. Java as well offers many other, more sophisticated tools, that might suit your needs much better.

In example if you want "precise" timing, you can instead use a ScheduledExecutorService, which uses the OS scheduling service to offer a precision of at least milliseconds, and often even nanoseconds. Although it is not exact to the nanosecond (despite the offer), it will usually be much more accurate than Thread.sleep. But both will not be accurate on a heavily overloaded system. If this is sufficient for your problem, then you should go with this. Otherwise you need a different language/execution environment.

Is Thread.sleep(x) accurate enough to use as a clock in Android?

No it is not accurate at all,

From the docs:

(temporarily cease
execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.

In other words, this sleep is OS or environment dependant, you can't predict the OS scheduling decision, plus, the sleep can be terminated by an interrupt.

Again from the docs:

In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified

Moreover, it is not efficient because you will be wasting CPU cycles just for sleeping.

ScheduledExecutorService will provide a better precision and performance.
Simply wrap your task in Callable or Runnable and use ScheduledExecutorService to execute them, there are plenty of tutorials out there.

.net thread.sleep inaccurate

As mentioned, accurate timings generally need a thread/process that is not going to time sliced out, to do this, you must Spin rather than Sleep.

Option 1

If you want absolute accuracy over anything else, I would use a dedicated high priority thread with a Stopwatch.

bool running = true;
Thread t = new Thread(() =>
{
Stopwatch sw = Stopwatch.StartNew();
while (running)
{
if (sw.ElapsedMilliseconds >= 20)
{
RunCode();
sw.Restart();
}
}
}) { Priority = ThreadPriority.Highest, IsBackground = true };

t.Start();

// ...

running = false;
t.Join();

Option 2

Bit more slimmed down, doesn't run on a different thread but still spins.

while (true) 
{
SpinWait.SpinUntil(() => false, TimeSpan.FromMilliseconds(20));
RunCode();
}

Option 3

Some open source high resolution timer code. e.g. https://gist.github.com/HakanL/4669495

Is the precision of Thread.Sleep still poor?

The precision of Thread.Sleep (and the underlying Windows API Sleep function in kernel32) is dependent on the resolution of the system clock, which has a default tick rate of roughly 15 ms. Applications can request a higher resolution, in which case the highest requested resolution is used globally.

In this case case, you're likely seeing sub-15 ms resolution because something running on your system has requested a higher resolution.

If your application actually needs sub-15 ms sleeps, it can request a higher resolution via the native timeBeginPeriod function.

However, note that it is possible that the underlying timer device won't support your requested resolution, so it's not good practice to write code that relies on this behavior unless you're absolutely sure of the hardware your code will be running on.

Java thread.sleep(1) sleeping longer than 1 ms

The sleep() method in java puts the currently executing thread (in the running state) to sleep for 1 ms.

After 1 ms the thread comes to runnable state (able to run), now it depends on the scheduler when to take the thread from the runnable state and execute it (i.e, running state).

For this reason, you can assume that the thread sleeps for a minimum of 1ms before running again.

Below figure describes the different thread states:
Sample Image



Related Topics



Leave a reply



Submit