The sleep() (on Python 2.3, Win32, at least) has a .001s limit. Is it lower/better on other's platforms?
I tried this test code, 2.4GHz P4
Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on win32
import time
t0 = time.clock()
t1 = time.clock()
t2 = time.clock()
t3 = time.clock()
t4 = time.clock()
t5 = time.clock()
print (-t0+t5)/5.
print t1-t0
print t2-t1
print t3-t2
print t4-t3
print t5-t4
>>>
ave 0.000342754564927
0.000321028401686
0.00030348379596
0.000297101358228
0.000295895991258
I had also considered forking a thread that would spin a loop checking time.clock() and firing the TTL pulse after the appropriate interval, but the real, ultimate resolution of time.clock() appears to be ~.00035s. If I increase process priority to real-time, it is ~.00028s and more stable.
I also tried some other code - times.py (attached)
suggested by:
http://66.102.7.104/search?q=cache:bLJ1F3Xxl-sJ:edily.progiciels-bpi.ca/showfile.html%3Fname%3Dcourriel/c%C3%A9duleur%26index%3D1+accuracy+time+sleep+python&hl=en&client=firefox-a
Note lines 15, 16, 17 - I still don't get why it (kind of) works.
15 and 17 have no different results when you ask for a delay<.001 (.001 is the slowest sleep() possible). But, it would seem that this should be forcing the minimum delay over 1000us!
For mydelay(.00016) the results are stable, but for mydelay(.000016) the actual average delay trends down. (!)
I then tried compiling an exe that uses select(), but it fails to delay:
#include <winsock2.h>
int main()
struct timeval time;
time.tv_sec = 10;
time.tv_usec = 100000;
select (0, NULL, NULL, NULL, &time);
return 0;
}
I then tried Python socket() - ~consistent, but the time control is not possible: In select(iwtd, owtd, ewtd[, timeout]) the timeout gotten "jumps" relative to the asked-for time when using small times (<.001), ie, .000001=>976us, .0000009=>79us.
I also tried a shot at compiling a command exe to do delays with RDTSC from:
http://216.239.63.104/search?q=cache:_HdQc03oTAIJ:www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20556300.html+accuracy+time+sleep+python&hl=en&client=firefox-a
using RDTSC - Read Time Stamp Counter info:
http://www.midnightbeach.com/jon/pubs/rdtsc.htm
I called it dosDelay (attached), but it does not seem to do any delaying...
I would make it a Windows or Python DLL if it did, RDTSC would be a great timing boon to those using 586 CPUs. On Windows there is still the multi-task issue, but setting the process to real-time helps a lot. R-T Linux users would benefit also.
Ray
http://rjs.org
import time mytime = time.time ## optimization sleep = time.sleep clock = time.clock
def mydelay(delay): global logical_time physical_time = mytime() try: logical_time = logical_time + delay except NameError: logical_time = physical_time + delay if logical_time > physical_time: sleep(logical_time - physical_time) #sleep(.0001) ## same as sleep(0)! #sleep(.001) p = 0. d1 = 0. d2 = 0. looped = 0. howMany = 100 for i in range(20): ## timer for pass in a for loop t1 = clock() for j in range(howMany): pass p += (clock()-t1) t1 = clock() for j in range(howMany): mydelay(.0000001) ## ~minumum useable d1 += (clock()-t1) t1 = clock() for j in range(howMany): mydelay(.00016) ## one turbine degree d2 += (clock()-t1) looped+= howMany print 'micro sec: %.1f %.1f %.1f' % (1000000*p/looped, 1000000*d1/looped, 1000000*(d2)/looped)
import time import select import socket HOST = '' # Symbolic name meaning the local host PORT = 50007 # Arbitrary non-privileged port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) mytime = time.time ## optimization sleep = time.sleep clock = time.clock p = 0. d1 = 0. d2 = 0. looped = 0. howMany = 100 for i in range(20): ## timer for pass in a for loop t1 = clock() for j in range(howMany): pass p += (clock()-t1) t1 = clock() for j in range(howMany): select.select([s], [], [], .0000009) #select.select([s], [], [], .000001) ## causes a timing jump! d1 += (clock()-t1) t1 = clock() for j in range(howMany): select.select([s], [], [], .0004) d2 += (clock()-t1) looped+= howMany print 'micro sec: %.1f %.1f %.1f' % (1000000*p/looped, 1000000*d1/looped, 1000000*(d2)/looped)
// dosDelay.cpp : Defines the entry point for the console application. struct sysclock_t { int LL, LH, HL, HH; }; struct tv time; time.tv_sec = num_seconds_to_sleep; time.tv_usec = num_microseconds_to_sleep; select(NULL,NULL,NULL,& time); void main() { int ns= 1000000; // make the sleep in 100th nanoseconds. ns = (ns + 99)/100; //ns -= FACTOR; __asm { rdtsc // clock in EDX:EAX // we ignore EDX since we asume ns is // of shorter duration than that. add eax,dword ptr ns mov ebx,eax // save eax into ebx. jnc loop2 // new time is after wrapping around loop1: rdtsc // again we ignore EDX // wait for time to wrap around. cmp eax,ebx jae loop1 // Time has wrapped around and present time < wait time. loop2: rdtsc // again we ignore EDX cmp eax,ebx jb loop2 } }
_______________________________________________ Python-win32 mailing list Python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32