[SOLVED] Running Psychopy in Ubuntu shows half the normal refresh rate

Hi everyone,

My lab has recently changed the set up of the EEG and stimuli PCs, and we are now running on Ubuntu but with a Windows 7 partition. The code for my experiment runs fine on the Windows partition, at the full 144Hz that it should (printed refresh rate at the start and checked with the benchmark wizard). However if I run the same experiment from within Ubuntu I get 72Hz, both from the benchmark wizard and printing at the start. The experiment does also take twice as long.

I tried reducing the refresh rate in case it was too fast for the script (I am loading images each trial) to 85Hz, but again on Ubuntu I was then getting 42.5Hz, again half of what it should be. I saw someone else on here found that reducing the resolution helped, but this did not work for me. In fact, I think it made it even worse.

I am not very familiar with Ubuntu so I’m not really sure how to go from here. While I do have the option of running things from Windows, it’s important that I get things running on Ubuntu.

Apologies if I am unable to provide more information for the next few days as I am travelling for work.

Thanks,
Gabriela

Yes, we’ve seen this before. It seems like a clash between psychopy waiting for the refresh to complete but ubuntu desktop also waiting for the refresh. The result is a double wait. Turn off waitBlanking in the PsychoPy Window and you should be fine. We’re talking about how to detect this issue automatically and do it for you but haven’t worked out how yet.

Thanks for the quick reply, this solved the problem entirely! I’ll let everyone in my lab know how to avoid the issue.

Just to add to this: I experienced the same problem (Ubuntu 16.04, psychopy 1.83.04) and solved it by turning off “Sync to VBlank” in my NVIDIA settings app. The advantage is that I can send the code to collaborators without deleting the waitBlanking. Of course, you have to be sure that you really want to disable vsync system-wide, but unless you’re a gamer, it shouldn’t really affect any activities.

I had the same problem on Arch Linux with the proprietary nvidia drivers and I also solved it by turning off “Sync to VBlank”. I think it may have only happened when the monitor was rotated. I have never had this issue with ATI cards (either with the open source or proprietary drivers) or Intel cards. I don’t have a nvidia card anymore to test, but it should be possible to programmatically detect the nvidia driver and the vblank sync setting (and probably change it).

@daniel.e.shub, My monitor is rotated as well! There’s no problem on Windows on the same hardware.

Just to add a wrinkle to this, in Arch on my machine at least (non-rotated monitor) - the ‘Sync to VBlank’ setting doesn’t seem to persist across X restarts without re-opening ‘nvidia-settings’. It will show as unchecked (i.e. no need to disable it again), but without re-opening ‘nvidia-settings’ it will be (functionally) ‘on’ and the refresh will be incorrect.

For example:
Test refresh = 30Hz
Open ‘nvidia-settings’, uncheck 'Sync to VBlank’
Test refresh = 60Hz
Restart X
Test refresh = 30Hz
Open ‘nvidia-settings’, ‘Sync to VBlank’ is still unchecked
Test refresh = 60Hz

This seems to be back again in my setup. Linux 4.9.35, Nvidia Driver 384.47, GTX1060 3G, BenQ 2730 . After tweaking the monitor and fiddling with the driver I can get 7 ms refresh rates as verified with a scope. The problem is that I get 2 frames of everything (rock solid) instead of 1.

in a loop, I do

DOT1.draw()
the_screen.flip(clearBuffer=True)
the_screen.flip(clearBuffer=True)

Reliably produces 2 white frames (screen background colour) then 2 black frames ( dot is black ).

I have tried adding a 2 ms delay between flips. No change. I have also tried the combinations of
waitBlanking =False and toggling the Vblank and Flipping in the Nvidia settings… Most every
combination makes the drawing worse ( tearing, variable # frames on/off, etc. )

Any suggestions?

Hi, I have a similar problem, using BUILDER, such that a frame refresh that should be 120Hz is reported in the output as 60Hz. I’ve posted the problem under the “Builder” forum:

Can anyone here lend some advice (preferably for “Builder”)?

Thanks very much in advance,
Ryan

Did you try this specific solution in the thread you linked to? That’s what did it for me. If you have an Nvidia video card, go into Nvidia settings app and uncheck Sync to VBlank.

@mdc has recently added support for a new backend (glfw) into the repository, which is going into the new release. I’m very interested if someone with an ubuntu box that shows the problem could see if it goes away when using

win = visual.Window(fullScreen=True, winType='glfw')

It would be nice not to need to turn off vsync in the driver settings and I do just wonder it the issue is to do with the way pyglet creates its windows (in the same way that it appears to be pyglet that creates the limitations of not-fullscreen on secondary mac displays).

Unfortunately my own ubuntu installation doesn’t have the issue so I can’t test myself

Just to add to Jon’s post, the GLFW backend’s v-sync settings are a bit more complicated than the usual Pyglet version. By default it’s enabled as expected, but the waitBlanking argument does not control it. To make v-sync behave like the Pyglet backend, you must supply ‘waitBlanking’ and ‘swapInterval’ arguments.

# create a window with V-Sync ON
win = visual.Window(fullScreen=True, winType='glfw', waitBlanking=True, swapInterval=1)

# create a window with V-Sync OFF
win = visual.Window(fullScreen=True, winType='glfw', waitBlanking=False, swapInterval=0)

By default, waitBlanking is True and swapInterval is 1, so you don’t need to worry about it unless you want to switch it off.

I’m going to include logic soon that will allow v-sync to be set using only waitBlanking.

Many thanks for the replies! I’ve tried several solutions, and the original win.waitingBlank=False may be the best one after all: when I set win.waitingBlank=False, the data output .csv file erroneously shows the framerate as 60Hz (see photo2), BUT when I check the logfile, the frames seem to be correctly presented at a 120Hz frequency: the log file (see photo1) shows that an image that I’ve specified to be displayed for 12 frames is logged correctly as 100ms duration (i.e., at 120Hz refresh rate; i.e., 1 frame =8.333ms) – not 200ms (which would have been the case if the monitor used a 60Hz refresh rate; i.e., 1frame =16.666 ms).

So, unless there is any problem that I’m not aware of, this bug may now be relegated to a more superficial bug, where frames are correctly being displayed at 120Hz, but the output file mistakenly shows “60hz”. Still, it would be nice to get rid of this bug, so I tried the other codes that you recommend:
win = visual.Window(fullScreen=True, winType=‘glfw’)
win = visual.Window(fullScreen=True, winType=‘glfw’, waitBlanking=False, swapInterval=0)

For both, I see an error message (photo 3) – note I’m using Builder, but that shouldn’t make a difference should it?
Many thanks,
Ryan

Forum2Forum1

Hello,

Are you using version 1.90 (development)? Any previous version would crash if ‘swapInterval’ is supplied. Also the argument is ‘fullscr’ not ‘fullScreen’, sorry about that.

Thanks. I’m using 1.85.3. I’m hesitant about installing an updated version (1.9) because it took a long time for my lab (we are all new to Linux) to install the last version and get it working - given that I’m collecting data at the moment (plus project students) it’s best to wait until data collection is over before I try anything like that. At the moment, I’m happy with the fact that win.waitingBlank=False fixes the timing problem (see my previous message); What would the new code (below) do differently? Would you also expect it to fix the other bug I reported (previous message) where frameRate is reported as 60Hz?

win = visual.Window(fullScr=True, winType=‘glfw’, waitBlanking=False, swapInterval=0)

The suggested code is to see if the new GLFW backend in 1.9 will fix the problem without having to resort to hacking display settings, directed to people who are experiencing the problem and can spare resources to test it out. I recommend not upgrading if its already working in your production environment.

I’ll just leave it here in case someone come looking for how to “tell” PsychoPy not to wait for the vertical retrace using Builder.

Just add a Code component at the begining of your experiment flow. In the tab Begin Experiment add the following line:

win.waitBlanking = False

PS: there is a typo in some comments of this thread. The argument is waitBlanking and not waitingBlank :wink: