Accurate Sleep for Java on Windows

Accurate Sleep for Java on Windows

To improve granularity of sleep you can try the following from this Thread.sleep page.

Bugs with Thread.sleep() under Windows

If timing is crucial to your
application, then an inelegant but
practical way to get round these bugs
is to leave a daemon thread running
throughout the duration of your
application that simply sleeps for a
large prime number of milliseconds
(Long.MAX_VALUE will do). This way,
the interrupt period will be set once
per invocation of your application,
minimising the effect on the system
clock, and setting the sleep
granularity to 1ms even where the
default interrupt period isn't 15ms.

The page also mentions that it causes a system-wide change to Windows which may cause the user's clock to run fast due to this bug.

EDIT

More information about this is available
here and an associated bug report from Sun.

Precise thread sleep needed. Max 1ms error

From the question tags I suppose you are on windows.
Take a look at Multimedia Timers, they advertise precision under 1ms.
Another options is to use Spin Locks but this will basically keep a cpu core at maximum usage.

Thread.sleep() optimization for small sleep intervals

That's easy to test:

public class Test {

static int i = 0;
static long[] measurements = new long[0x100];

static void report(long value) {
measurements[i++ & 0xff] = value;
if (i > 10_000) {
for (long m : measurements) {
System.out.println(m);
}
System.exit(0);
}
}

static void sleepyWait() throws Exception {
while (true) {
long before = System.nanoTime();
Thread.sleep(1);
long now = System.nanoTime();
report(now - before);
}
}

static void busyWait() {
while (true) {
long before = System.nanoTime();
long now;
do {
now = System.nanoTime();
} while (before + 1_000_000 >= now);
report(now - before);
}
}


public static void main(String[] args) throws Exception {
busyWait();
}
}

Run on my windows system, this shows that busyWait has microsecond accuracy, but fully uses one CPU core.

In contrast, sleepyWait causes no measurable CPU load, but only achieves millisecond accuracy (often taking as much as 2 ms to fire, rather than the 1 ms requested).

At least on windows, this is therefore a straightforward tradeoff between accuracy and CPU use.

It's also worth noting that there are often alternatives to running a CPU at full speed obsessively checking the time. In many cases, there is some other signal you could be waiting for, and offering an API that focuses on time-based resolution may steer the users of your API in a bad direction.

Accurate Sleep with cancellation

You shouldn't be implementing this at all.

In C++11 all basic necessary utilities for multithreading are implemented in the standard.
If you do not use C++11 - then switch to C++11 or higher - in the unfortunate case that you cannot, then use Boost which has the same features.

Basically, what you want to do with this functionality is covered by std::condition_variable. You can put a thread into waiting mode by using function wait (it accepts a condition function necessary for leaving the wait), wait_for and wait_until (same as wait but with total waiting time limit) as well as notify_one and notify_all methods that wake the sleeping threads (one or all) and make them check the awakening condition and proceed with their tasks.

Check out std::conditional_variable in the reference. Just google it and you'll find enough information about it with examples.

In case you do not trust std::conditional_variable implementation for some reason, you can still utilize it for mini waits and awakening.

How Java precise sleep under 1ms

Game engines relies on Delta time for making games frame rate independent, Delata time is nothing but elapsed time between the last frame and current frame.
You can measure delta time as

DeltaTime = 1/FPS

So you can use this variable to make the game independent by multiplying this with your game variables, for example if you want to move a player independent of Frame rate you would do something like

Player.position = Player.position + MovementSpeed * DeltaTime

If initial position = 10 , MovementSpeed = 1
If FPS = 60, DeltaTime = 0.016666667 then distance after 1 second is

Player.position = 10 + 1 * (0.016666667*60) which is '11'
(Here it's multiplied with 60 to simply acomodate the fact that same calculation will run for 60 times when game is running at 60 FPS so Player.position will be updated by 0.016666666 for 60 Times)

If FPS = 30 , DeltaTime = 0.03333 then distance moved after 1 seconds is
Player.position = 10 + 1*(0.03333*30) which is '11'
So game can run independent of Frame Rates

You could try to calculate DeltaTime like:

//In main Game loop
current time = getSystemTime()
Delta time = current time - old time
old time = current time // save old time for next loop

Is sleep method accurate in timing precision?

Sleep is not the thing you want, as in here.
I suggest to read through this.

Thread.sleep and System.currentTimeMillis

Thread.sleep causes the currently executing thread to sleep
(temporarily cease execution) for the specified duration, subject to
the precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors, and resumption of execution
will depend on scheduling and the availability of processors on which
to execute the thread.

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



Related Topics



Leave a reply



Submit