[psychopy-users] OS time-slicing, python and psychopy

171 views
Skip to first unread message

Kaushik Ghose

unread,
May 10, 2010, 12:41:22 PM5/10/10
to psychopy-users
Hi Gang,

I have been looking into events and threading in python and came up
against the concepts of OS time-slicing. From what I read, the only
way to change the time slice is to recompile the kernel to do smaller
time-slices. Is this correct?

Does this mean that everytime I give up my thread I can only get it
back in (typically) 10ms or more?

I ask this because I have a small app doing an event loop that polls
for events. If I have the loop run as fast as possible I get polling
runs at 44 kHz or so but it grabs 100% CPU and sets off the fans etc.

I put in a sleep statement in the loop. That works fine to calm down
CPU usage, but I can not sleep for less than 10ms (which I now
discover is related to OS time-slicing).

I tried to use event driven code (using pythons Queue object) and it
works fine, but I still run up against the 10ms latency.

Is this the 'granularity' of response times we can get without hogging
the CPU, or is there some trick to not hog the CPU but still have
really small response times?

Best
-Kaushik

--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To post to this group, send email to psychop...@googlegroups.com.
To unsubscribe from this group, send email to psychopy-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/psychopy-users?hl=en.

Jon Peirce

unread,
May 11, 2010, 4:35:22 AM5/11/10
to psychop...@googlegroups.com
I confess I'd never investigated this - I knew that time.sleep() had a poor resolution but not gone further.

But, looking around I've found that wx has routines called MilliSleep and MicroSleep for this purpose. For my standard Snow Leopard machine MilliSleep is pretty good:

>>> import wx, time
>>> t0=time.time(); time.sleep(0.001); print time.time-t0
0.0100209712982
>>> t0=time.time(); wx.MilliSleep(1); print time.time()-t0
0.00115704536438

For win32 you should use time.clock() to do the measuring, but it does seem that there's this fixed resolution - using wx.MilliSleep(1) results in a 10-15ms sleep, at least on XP, I haven't tried on vista/7 where it may be different.

Haven't tried on linux, but i expect it to be similar to os x. Could someone give it a go?

So Kaushik, I think it will depend on your system, but this may be a step forwards. Thanks for the nudge - as a result I'll be improving the resolution of psychopy.core.sleep() using wx.MilliSleep() where possible.

Jon


On 10/05/2010 17:41, Kaushik Ghose wrote:
Hi Gang,

I have been looking into events and threading in python and came up
against the concepts of OS time-slicing. From what I read, the only
way to change the time slice is to recompile the kernel to do smaller
time-slices. Is this correct?

Does this mean that everytime I give up my thread I can only get it
back in (typically) 10ms or more?

I ask this because I have a small app doing an event loop that polls
for events. If I have the loop run as fast as possible I get polling
runs at 44 kHz or so but it grabs 100% CPU and sets off the fans etc.

I put in a sleep statement in the loop. That works fine to calm down
CPU usage, but I can not sleep for less than 10ms (which I now
discover is related to OS time-slicing).

I tried to use event driven code (using pythons Queue object) and it
works fine, but I still run up against the 10ms latency.

Is this the 'granularity' of response times we can get without hogging
the CPU, or is there some trick to not hog the CPU but still have
really small response times?

Best
-Kaushik

  

This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.

Jon Peirce

unread,
May 11, 2010, 5:11:45 AM5/11/10
to psychop...@googlegroups.com
On second thoughts, maybe it isn't worth using wx.MicroSleep in core.wait(). The hogCPU method is still the best way to handle the short periods that we're likely to need it for and importing wx slows down the import of psychopy.core considerably.


Jon

On 10/05/2010 17:41, Kaushik Ghose wrote:
Hi Gang,

I have been looking into events and threading in python and came up
against the concepts of OS time-slicing. From what I read, the only
way to change the time slice is to recompile the kernel to do smaller
time-slices. Is this correct?

Does this mean that everytime I give up my thread I can only get it
back in (typically) 10ms or more?

I ask this because I have a small app doing an event loop that polls
for events. If I have the loop run as fast as possible I get polling
runs at 44 kHz or so but it grabs 100% CPU and sets off the fans etc.

I put in a sleep statement in the loop. That works fine to calm down
CPU usage, but I can not sleep for less than 10ms (which I now
discover is related to OS time-slicing).

I tried to use event driven code (using pythons Queue object) and it
works fine, but I still run up against the 10ms latency.

Is this the 'granularity' of response times we can get without hogging
the CPU, or is there some trick to not hog the CPU but still have
really small response times?

Best
-Kaushik

  

This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.

--

Jeremy Gray

unread,
May 11, 2010, 7:21:24 AM5/11/10
to psychop...@googlegroups.com
this is what I get on ubuntu 9.10 in a virtual machine (which is suboptimal for this test)

>>> t0=time.time();time.sleep(.001);time.time()-t0
0.0012371540069580078
0.0012729167938232422
0.0011928081512451172

>>> t0=time.time();wx.MilliSleep(1);time.time()-t0
0.0012428760528564453
0.0011827945709228516
0.0013568401336669922

Kaushik Ghose

unread,
May 11, 2010, 8:07:41 AM5/11/10
to psychopy-users
Jon, Jeremy,
Thanks for your replies. Mac OS X is a sluggard.

import time
t0=time.time();time.sleep(.001);time.time()-t0
-> 0.01031494140625

import wx
t0=time.time(); wx.MilliSleep(1); print time.time()-t0
-> 0.0186131000519

So, Jon, if I understand right: psychopy does its time sensitive part
by hogging the CPU during the polling?

Thanks

Kaushik Ghose

unread,
May 11, 2010, 8:09:55 AM5/11/10
to psychopy-users
Woops. Must have been some issue with running this the first time.
Because now it gives

t0=time.time();wx.MilliSleep(1);time.time()-t0
-> 0.0011050701141357422

Jon Peirce

unread,
May 11, 2010, 10:40:59 AM5/11/10
to psychop...@googlegroups.com
yeah, i was surprised by that, having had it work quite well under 10.6, but wondered if you were running 10.5

But yes, psychopy has a wait() function in core.py that uses time.sleep initially and then hogs cpu for final customisable period (default 200ms to be very safe).


On 11/05/2010 13:09, Kaushik Ghose wrote:
Woops. Must have been some issue with running this the first time.
Because now it gives

t0=time.time();wx.MilliSleep(1);time.time()-t0
-> 0.0011050701141357422

On May 11, 8:07 am, Kaushik Ghose <kaushik.gh...@gmail.com> wrote:
  
Jon, Jeremy,
Thanks for your replies. Mac OS X is a sluggard.

import time
t0=time.time();time.sleep(.001);time.time()-t0
-> 0.01031494140625

import wx
t0=time.time(); wx.MilliSleep(1); print time.time()-t0
-> 0.0186131000519

So, Jon, if I understand right: psychopy does its time sensitive part
by hogging the CPU during the polling?

Thanks
    
  

This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.

--
Reply all
Reply to author
Forward
0 new messages