Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python time.sleep vs busy wait accuracy

I was playing around with the time.sleep function from python's standard library and found it inadequate for sub-ms delays. From testing I found it to actually wait 1.1-1.2 ms for a 1ms wait. Implementing a busy wait got the accuracy to within 1%. I used:

def busy_wait(dt):   
    current_time = time.time()
    while (time.time() < current_time+dt):
        pass

and could get down to 0.0001 seconds before breaking 1% accuracy.

The main questions I have are:

  • Why is the sleep function so inaccurate (possibly a C issue)? Will getting a better CPU with a higher clock speed change this?
  • Why would anyone use sleep? The only advantage I see, power conservation, is limited to embedded systems, no?
  • Would it be viable to compensate for sleep's inaccuracy with calibration? Like so:
def sleep(dt):
    sleep(calibration_function(dt))

As an aside, I read that sleep doesn't even function well with long wait times: Upper limit in Python time.sleep()? I also read somewhere on SO of making a loop of shorter time intervals to increase precision, but that is useless when I want to delay 0.01 sec. Karl Voigtland mentions using ctypes' nanosleep, but I feel this is overkill and that time.sleep should do it's intended behavior.

time.sleep is a broken python feature? Or does nobody care about accurate time measurement enough?

like image 436
JDong Avatar asked Jul 06 '13 05:07

JDong


Video Answer


1 Answers

On Windows the OS Sleep function (which Python necessarily uses) can only wake up a thread on a multiple of the current timer interval. Typically this ranges between 1.0 ms and 15.6 ms. Lowering the timer interval can be handy because it allows for shorter sleeps, but it wastes electricity, as I wrote about in this article:

http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/

Busy waiting may give better accuracy but is generally a horrible idea since it wastes even more electricity and steals CPU time from more deserving tasks:

https://randomascii.wordpress.com/2012/06/05/in-praise-of-idleness/

Finally, the accuracy of busy waiting will depend on what timer function you are using to get the current time, and may also depend on the timer interval:

https://randomascii.wordpress.com/2013/05/09/timegettime-versus-gettickcount/

Why do you want to sleep for such short time periods? Usually it would be better to wait for something to happen -- waiting on an event -- rather than waiting for such short time periods.

like image 127
Bruce Dawson Avatar answered Sep 19 '22 19:09

Bruce Dawson