psychopy.org | Reference | Downloads | Github

Win.flip() takes very little time after core.sleep()

Dear community,

I stumbled over a funny behavior that I don’t quite make sense of. Perhaps someone could it explain it to me.

It seems like that after core.wait() is called, the first few win.flip()s are really short, much shorter than the refresh rate of my monitor would allow. The exact number of how often this happens varies (some times only two flips, sometimes 5-6), I couldn’t find a system in it yet.

Here is some example code that illustrates the problem. The only difference between the two loops is whether the core slept or not.

from psychopy import visual, core

win = visual.Window(color=(0,0,0),fullscr=1, units="pix")
exp_frames = round(0.15*60) # 0.15 seconds at 60Hz

for i in range(4):
    core.wait(0.995)
    print("core slept.".format(i=i))
    for frame in range(exp_frames):  
        t1=core.getTime()
        win.flip()
        print("frametime: ", core.getTime()-t1)

for i in range(4):
    print("core did not sleep.".format(i=i))
    for frame in range(exp_frames):  
        t1=core.getTime()
        win.flip()
        print("frametime: ", core.getTime()-t1)

win.close()
core.quit()

As I can rather easily program around that issue, it is more of theoretical relevance. But still, I’d like to understand what is going on here.

Thanks,
Eduard

  • Don’t use print() for real-time outputs - that can slow things down. use the logging system, or add values to a list and print it out when you’re finished.
  • The short duration is expected for the first frame at least. When you use sleep or wait functions, you aren’t staying in sync with the screen drawing cycle, so when the code re-starts after the .wait() period, you will be some random time in between successive screen refreshes. So with a 60 Hz display, the t1 value could be anywhere between 0 and 16.7 ms before the next win.flip() completes (on average, a uniform distribution with mean -8.3 ms).
  • Once you have gotten beyond the first win.flip(), cycles should now be regular, but you would be better off measuring the successive intervals between the time returned from win.flip(), rather than measuring the time before and after it, which will have a (very small) noise.