High resolution sleep (Linux)

Nick Craig-Wood nick at craig-wood.com
Sat May 5 06:30:03 EDT 2007


John <janzon at gmail.com> wrote:
> 
>  The table below shows the execution time for this code snippet as
>  measured by the unix command `time':
> 
>  for i in range(1000):
>  	time.sleep(inter)
> 
>  inter       execution time      ideal
>  0                     0.02 s            0 s
>  1e-4                4.29 s            0.1 s
>  1e-3                4.02 s            1 s
>  2e-3                4.02 s            2 s
>  5e-3                8.02 s            5 s
> 
>  Hence it seems like the 4 s is just overhead and that the time.sleep
>  method treats values below approximately 0.001 as 0.

The exact minimum sleep time will be determined by the HZ value that
your kernel was compiled with.  In newer kernels that is typically 250
or 1000, it used to be 100 in older kernels.

If you look at the config file used to build your kernel you can
discover the HZ value.

If you try to sleep for less than a timer tick, then the kernel
performs a yield.

>  Is there a standard way (or slick trick) to get higher resolution? If
>  it is system dependent it's acceptable but not very nice :)

I assume you are using sleep for timing purposes..  This isn't a
terribly good idea, but here is an idea for you....

# ------------------------------------------------------------
from time import time, sleep

def hr_sleep(duration):
    end = time() + duration
    if duration > 0.02:
        sleep(duration)
    while time() - end < 0:
        sleep(0)

if __name__ == "__main__":
    from timeit import Timer
    for e in range(0,7):
        dt = 10**-e
        loops = 10**e
        t = Timer("hr_sleep(%f)" % dt, "from __main__ import hr_sleep")
        print "expected = %.2E actual = %.2E" % (dt, t.timeit(loops)/loops)
# ------------------------------------------------------------

This prints

expected = 1.00E+00 actual = 1.00E+00
expected = 1.00E-01 actual = 1.00E-01
expected = 1.00E-02 actual = 1.00E-02
expected = 1.00E-03 actual = 1.00E-03
expected = 1.00E-04 actual = 1.02E-04
expected = 1.00E-05 actual = 1.19E-05
expected = 1.00E-06 actual = 2.66E-06

on my 250 HZ machine

You could then do run-time calibration to work out the overhead of the
function on any given machine to make it more accurate.

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list