An input lag investigation

Hi ! Really enthusiastic to read what’s going on here. Great work !! Input lag has made me upset for years ! (which is why I tended to give up on emulation and use real hardware or FPGA machines). Just a stupid user question : what does the frame_delay option do ? I thought it had to be set to 0 to reduce lag ? Also, if would be great if other devs, inspired by your findings, could check other libretro cores… There are many games that are made difficult (or almost unplayable)… For instance, Star Soldier on the PC Engine ; Gigawing (MAME)…

Thanks!

Actually, it’s the other way around. What the frame delay setting does is that it delays the running of the emulator core (and the polling of input) a specified number of milliseconds after receiving vsync. This is actually a good thing. Normally, when frame delay is set to 0 ms, the emulator runs and generates the next frame immediately after receiving the vsync event. It then idles until the next vsync event. If the emulator runs in a short time, such as 1 ms, the wait period is almost a whole frame. It’s not until the next vsync event that the frame that was generated is actually passed on to the graphics pipeline for display. So, after receiving vsync, the ideal thing to do is to wait with polling input and running the emulator for as long as possible and instead run it as close to the next vsync as possible. This way, the time you’d otherwise spend on just waiting can be used to accept input.

The frame delay setting is specified in milliseconds and it’s the performance of the system/emulator (i.e. the time it takes to run the emulator loop) that decides how high you can set it. The faster the emulator runs, the higher you can put this setting. I managed 12 ms on my Core i7-6700K when running Nestopia and snes9x-next. This corresponds to a reduction of input lag of 12 ms or ~0.7 frames.

Noobish question : do I have to change frame delay to something else than zero, if I have a Gsync monitor ? Or is that irrelevant ?

Thanks for the quick reply ! Hmm, if I understand correctly, if you wait for half a frame (about 8 ms)after the vsync, you need twice the CPU power to render the frame in half the time ? So, when using a slow CPU (Raspberry Pi) one has to check the ideal value for each platform I guess. For instance on my Pi 3 it seems a value of 8 is good for the Neo Geo ; but the PGM platform requires me to set it very low.

I’m not 100% sure, but I would guess that you’d want it at zero in the Gsync case.

[QUOTE=bidinou;41845]Thanks for the quick reply ! Hmm, if I understand correctly, if you wait for half a frame (about 8 ms)after the vsync, you need twice the CPU power to render the frame in half the time ? So, when using a slow CPU (Raspberry Pi) one has to check the ideal value for each platform I guess.[/QUOTE] Yup, that’s correct. The frame delay basically decreases the time you have available to render the frame. On the Pi you don’t have that much extra performance. I would guess that a Pi 3 running snes9x-next could accept 4 ms tops and maybe 8 ms if running fceumm or Nestopia.

The main problem with this setting is that you have to manually tweak it for each host system and emulator.

May I ask a last question ? Did you measure any input lag difference with the video_threaded option ?

Thanks again ! I’m happy to know I can tweak one more setting :slight_smile:

Edit : value of 7 seems OK for Neo Geo and SNES on the Pi 3. I’ll try to pay more attention to subtle sound distortion and try more demanding titles. Edit : after further tests on Pi 3 / RetroPie : frame delay of 9 seems ok for Neo Geo & PSX, 5 for the SNES, 10 for the PC Engine & Megadrive (on Pi 3). No Edit : final values : SNES : 4 // Neo Geo & PSX : 9 / PC Engine : 9 // Megadrive : 10

Nope, I haven’t. I may give it a shot, but don’t count on it. Getting a bit sick of testing right now, to be honest. :stuck_out_tongue:

[QUOTE=bidinou;41847]Edit : value of 7 seems OK for Neo Geo and SNES on the Pi 3. I’ll try to pay more attention to subtle sound distortion and try more demanding titles. Edit : after further tests on Pi 3 / RetroPie : frame delay of 9 seems ok for Neo Geo & PSX, 5 for the SNES, 10 for the PC Engine & Megadrive (on Pi 3). No[/QUOTE] Thanks for testing. Give Yoshi’s Island a try. It’s a SuperFX game and it seems pretty demanding. It was the only game where I noticed slowdown on the Pi 2. Even if the Pi 3 is decent amount faster, there can’t be a huge margin left for frame delay.

Indeed, there is a slight slowdown on the menu with a frame delay of 5. It’s OK with 4. I give up to set this for MAME games :slight_smile:

Think it’s time to try RetroPie, Recalbox or Lakka again. Are the fixes to the emualtors already in the repository or do I have to manualy update them?

Just made a pull request for implementing the exact same fix for bsnes as bsnes-mercury: https://github.com/libretro/bsnes-libretro/pull/16

Hopefully they’ll both be merged very soon. :slight_smile:

[QUOTE=xadox;41852]Think it’s time to try RetroPie, Recalbox or Lakka again. Are the fixes to the emualtors already in the repository or do I have to manualy update them?[/QUOTE] I know RetroPie binaries have been updated with the fix for fceumm, but otherwise I’m not sure.

[QUOTE=xadox;41852]Think it’s time to try RetroPie, Recalbox or Lakka again. Are the fixes to the emualtors already in the repository or do I have to manualy update them?[/QUOTE] for retropie, you’ll have to update lr-fceumm and lr-snes9x-next via the retropie setup script via binaries.

Thanks brunnis. On Gsync it feels pretty reactive already.

You know what I’m doing now (well, in 10 secs)? Actually gaming, not performance testing, on my RetroPie setup. :smiley:

What settings are you using on your Raspberry Pi to get minimal input lag in addition to the emulator lag fixes?

These are my settings:

Raspberry Pi 3 [B]arm_freq=1200 core_freq=500 sdram_freq=500 gpu_freq=400

runcommand.sh cpu setting = performance

Input driver = udev Joypad driver = udev Video driver = dispmanx Audio driver = sdl2

Audio Latency = 32 Audio Output Rate = 44100[/B]

Vsync = On - games tear and stutter way too bad for me with this disabled Frame Delay = Depends on game - I set it as high as I can before audio starts to crackle HW Bilinear Filtering = Off

All shaders and overlays disabled

I’m able to get most NES games up to about frame delay 10 but SNES games can vary from 1 to 7.

[QUOTE=Heffer;41871]What settings are you using on your Raspberry Pi to get minimal input lag in addition to the emulator lag fixes?

These are my settings:

Raspberry Pi 3 [B]arm_freq=1200 core_freq=500 sdram_freq=500 gpu_freq=400

runcommand.sh cpu setting = performance

Input driver = udev Joypad driver = udev Video driver = dispmanx Audio driver = sdl2

Audio Latency = 32 Audio Output Rate = 44100[/B]

Vsync = On - games tear and stutter way too bad for me with this disabled Frame Delay = Depends on game - I set it as high as I can before audio starts to crackle HW Bilinear Filtering = Off

All shaders and overlays disabled

I’m able to get most NES games up to about frame delay 10 but SNES games can vary from 1 to 7.[/QUOTE] Only things I’ve changed on RetroPie are:

  • Use dispmanx video driver for 1 frame less input lag.
  • Set NES frame delay to 6 (could perhaps extend a little further). I don’t use frame delay on SNES, since even a setting of 2 caused audio issues in Yoshi’s Island.
  • video_threaded = ‘false’. Probably no effect on input lag.
  • video_smooth = ‘false’. Shouldn’t affect input lag.

The only settings I know for sure affect input lag on the Raspberry Pi are the video driver and the frame delay setting.

[QUOTE=Brunnis;41875]Only things I’ve changed on RetroPie are:

  • Use dispmanx video driver for 1 frame less input lag.
  • Set NES frame delay to 6 (could perhaps extend a little further). I don’t use frame delay on SNES, since even a setting of 2 caused audio issues in Yoshi’s Island.
  • video_threaded = ‘false’. Probably no effect on input lag.
  • video_smooth = ‘false’. Shouldn’t affect input lag.

The only settings I know for sure affect input lag on the Raspberry Pi are the video driver and the frame delay setting.[/QUOTE]

I haven’t done any testing but it “feels” as though there is some input lag tied to the audio latency. With audio set to 32 instead of 48 or 64 it seems more responsive since the audio and video are synced.

I can’t figure out how to do the pause test method on the RPi as I have to use the hotkey enable button to increment the frames and it won’t allow me to input any button presses while the hotkey button is held.

Audio latency does matter but it’s a perceptive issue rather than a visual/response issue in this case. If you see and hear 2 things that are supposed to happen at the same-ish time (within an approx. 80 ms window), your brain says “these two things happened at the same time,” matched to the slowest response. So, if you’re feeling like it’s more latent with higher audio latency, you should be able to mute it and feel the latency melt away, as if by magic.

So, you’ll want to get your audio latency down as low as possible, as well, to get the best feel. The JACK audio driver should allow for very low audio latency in Linux-based systems.

About overclocking… As the RPi 3 tends to heat a lot, it might have the opposite result after some minutes / hours as it’ll slow down if overheating. Hmm, although only 1 core is used and although the frame delay means even this one core is not used at 100%.

I couldn’t live without the shaders, though (crt-pi !). Maybe I could get used to a scaler with no bilinear and with good scanlines.

Thanks for sharing all this :)I used to be frustrated for months / years ago because so many people said they noticed no lag.

[QUOTE=hunterk;41884]Audio latency does matter but it’s a perceptive issue rather than a visual/response issue in this case. If you see and hear 2 things that are supposed to happen at the same-ish time (within an approx. 80 ms window), your brain says “these two things happened at the same time,” matched to the slowest response. So, if you’re feeling like it’s more latent with higher audio latency, you should be able to mute it and feel the latency melt away, as if by magic.

So, you’ll want to get your audio latency down as low as possible, as well, to get the best feel. The JACK audio driver should allow for very low audio latency in Linux-based systems.[/QUOTE]

Anything special needed to get the JACK driver to work with RetroArch on an RPi 3? I’ve set the driver to JACK and set the audio_device to hw:0,0 for the analog jack which is what I’m using and it just seems to crash when launching an emulator. I’m able to successfully start jackd manually from the shell.

EDIT: Never mind I got it working. I had to use: audio_device = “system:playback_1,system:playback_2” instead of hw:0,0

Can you set the audio latency significantly lower with jack enabled (as it can already be lowered with Alsa) Is the tradeoff in terms of cpu time worth it ?

Edit : here, with ALSA + a QAudio DAC+ sound addon, lowering the audio delay makes it necessary the reduce to video_frame_delay setting. So the right tradeoff between input and sound delays has to be figured out. No overclocking here. Methinks input latency prevails.