An input lag investigation

I was just comparing the input lag of my keyboard vs the input lag of my 8bitdo controller, and was surprised to find this: Connecting the controller via USB cable is laggier than connecting it by Bluetooth.

1 Like

I made some pretty pictures showing off various input lag I got.

Clips were taken with cellphone camera recording at 120FPS.

First, real NES on a CRT. On the third frame, finger comes in contact with the button, and top of screen is immediately brightened. Zero lag whatsoever.

In order to respond instantly to a button press, it’s using some custom Game Genie codes that change The Legend of Kage into a input lag tester.

inputlag_nes

Second, my little DX9 Input Lag tester program using the Enter key to trigger the display to change color. Despite updating the screen immediately, and showing tearing, it still manages to have about 16.66ms of lag before anything actually appears on the screen.

inputlag_keyboard

Third, using an 8bitdo controller instead of a keyboard. One more half-frame of lag than with the keyboard, very good for a bluetooth device.

inputlag_8bitdo

5 Likes

This matches my own findings with my 8bitdo SFC30. I measured 8-10 ms extra lag compared to a standard USB device. Quite good and a small number compared to the other usual input lag sources.

Acording to the DS4Windows, when using bluetooth, the Playstation 4 controller comunicates to 250hz(4ms) by default but selectable up to 1ms, and when using the cable the default usb comunication would be at 125hz(8ms). Maybe 4ms is default for every BT controller on Windows. Here some info about dx and its different presentation modes and latencies https://docs.microsoft.com/es-es/windows/desktop/direct3darticles/direct3d-9ex-improvements and https://www.youtube.com/watch?v=E3wTajGZOsA&list=PLeHvwXyqearWT_NT7CiGm_kEiKabWNPKw&index=7

My little test program is already using a zero-latency mode (Exclusive Fullscreen + Flip with vsync off), but thanks for linking that youtube video.

No problem. When usin 120hz refresh rates (crt, freesync, etc) I believe the latency is cut in half of that of 60hz (in conjunction with the use of a frame delay value close to 8 might eliminate the full frame of lag of the api). but the use of black frame insertion for smoothness, darkens the screen. The black frame insertion demo of blur busters site has a “brightness equalizer” to counter that https://www.testufo.com/blackframes#count=2&bonusufo=1&equalizer=1&background=000000 Can something similar be done for retro arch? maybe a shader or gama bust?

The brightness equalizer in that example unfortunately is going the other way :stuck_out_tongue:

It’s darkening the 30 fps and 60 fps by 50% rather than brightening the BFI one.

AFAIK, the only way to improve the brightness in BFI is to increase the brightness of the monitor. That is, if we try to increase it in software, we’re just going to get a bunch of clipping, as we’re already at the limits of brightness with a normal image.

1 Like

oh, I see. What about a gamma bust like the FPGA Super NT does, or even the FightCade version of FBA has a gamma setting(by both software and hardware methods) for compensating the scanline filter. Or what if we change the black frame to a gray or white frame instead, or that will result in a washed like image?

Sorry to go backwards and nooby on you Brunnis(and everyone else) but I’m having the hardest time googling an explanation on Windows 10 USB polling. I’ve read articles in the past on Windows about using PS/2 ports and all to cut usb lag but still don’t understand if it’s still an issue on W10. This post seems to say it does. Everytime I trying googling W10 usb polling, I get vague results talking about mouse and not gamepads and joysticks. So can you Brunnis or anyone else here help me understand how to fix it and if I buy an expensive HORI Joystick for PC does it have 1000hz automatically turned on so I can play fighters with no issue or do I have to manually set the polling? Or…someone can just point me in the right direction? Again really sorry to go backwards here guys but I have horrible google skills and it’s been years with no straight answers. Please help!!!

There is no latency/polling issue with USB in Windows. It all works automatically. The most commonly used (and slowest) polling frequency is 125 Hz, but devices themselves are free to request faster poll rates (250 Hz, 500 Hz and a maximum of 1000 Hz). The host system reads this device configuration info during bus enumeration and Windows will honor this out of the box.

Unfortunately, faster polling rates than 125 Hz are not all that common. For some reason, it’s mostly used for mice (which is probably why you mainly found info on this when googling). But, as long as the device you’re connecting requests faster poll rate, it will work fine. For example, I’m using the Raphnet Wii to USB adapter for my SNES Classic Mini controllers and it’s a 1000 Hz USB device. Windows handles this correctly.

In short: no manual configuration of poll rates is necessary.

By the way, trying to force a higher poll rate than what a device requests can be tricky, but that’s a different discussion. :slight_smile:

Could you elaborate on that?

In the past I stopped using Sweetlow’s USB hack, as I would find it behaving erratically even though USBView would show it changed the bInterval to 0x01 for the patched device.

Not really. :slight_smile: Well, it’s just that it usually requires hacks and third party tools, which may be tricky to implement (depending on the user’s computer knowledge, of course).

So what I picked up so far is that emulation vs real hardware + CRT is about 1 frame difference, is this accurate?

Also, is snes9x2010 still the best/low input lag core for snes? Should we use 2010 or 1.57 version that was released a few days ago if input lag is our main concern?

it’s far more nuanced than this but for emulators that work in slices of full frames (*and with vsync on the host), which is the most common type and the kind retroarch was designed to handle, that is more or less accurate. also, this assumes your gpu driver and hardware aren’t buffering frames outside of the emulator’s control and there exists a way to initiate the gpu into drawing the just submitted draw commands immediately (eg using video_hard_sync in retroarch when using the opengl driver). also, this doesn’t necessarily apply when emulating 3d systems where the graphics are handled via translating draw commands from the guest into equivalent ones on the host.

runahead can be used to mitigate this last single frame difference, and even surpass it in instances where the game is natively buffering inputs (like Super Mario World, for instance).

snes9x2010_libretro and snes9x_libretro should be identical in latency, provided your machine is fast enough to handle the latter.

*EDIT: forgot to mention this assumes vsync on the host, with vsync off and with conventional emulator design (ie not beam racing) it can be less than a frame difference, but then you’ll also have screen tearing.

1 Like

To add to what e-tank wrote:

By using a fast desktop computer and low latency (1000 Hz) USB controllers, I’ve gotten down to just ~5 ms (0.3 frames) average extra input lag compared to a real NES or SNES on a CRT. Regular USB (125 Hz) controllers will add a few ms to that, but still only ~0.5 frames of extra lag compared to the real consoles. To get input lag this low requires you to use the Frame Delay setting to eek out the last input lag reduction. Without using Frame Delay, ~1.0-1.2 frames is probably a good ballpark figure.

The above is without using run-ahead, by the way.

1 Like

holy crap that’s insane. and you’re using the newest SNES core too? thanks for the follow up man. great info.

what frame delay do you use? I tried 15 but it was way too much for my 7700k. settled on 12 but some games need to be dropped to 10 after setting up Runahead.

my buffalo USB snes controller seems to have the same Low and 0x0A interval, but PS4 controller connected via usb cable says Full and 0x05, which i think should actually be half the buffalo, 4ms. the buffalo experiences ghosting tho and I think PS4 one seems a bit laggy, maybe its DS4Windows. im getting an 8bitdo controller that I plan to use via usb, any ideas on the polling rate on that when connected via USB?

oh and one last thing, do you bother with Audio Latency or just leave it at the default 64ms?

I use snes9x2010 since it executes slightly faster, which allows for a (slightly) higher frame delay setting. I haven’t really had any issues with snes9x2010, otherwise I would just switch to snes9x. There’s no difference in input lag with the cores themselves.

I believe I got a frame delay of 13 or 14 to work on my 6700K @ 4.4GHz. The trick is to disable the power management of your Nvidia GPU. I have a GTX 1080 and disabling the power management in the Nvidia settings bought me ~2 ms extra on the frame delay.

Yeah, I also have a few of those Buffalo controllers. Most of them seem to have the ghosting issue and I actually devised a way of more or less fixing them. It requires soldering a few capacitors though. The good news is that the latency in the controller is otherwise actually really good. There’s no additional latency other than that caused by the standard 125Hz USB polling, so 4 ms average and 8 ms max.

I think 8bitdo uses 125Hz polling as well. 125Hz is really quite okay and I probably wouldn’t spend a lot of money just to get something with faster polling rate. I do use the SNES Classic Mini controllers with expensive adapters, but I did that mostly for the quality controller and not for the improved latency.

Please note that some controllers have internal latency not related to USB and those are important to avoid. The Retro-Link SNES replica I used for my initial input lag tests has this kind of lag, probably caused by some internal button polling loop not related to the external USB polling.

I haven’t played around much with audio latency, but I believe I use 48 ms on my current RetroArch installations. I’m not nearly as sensitive to audio latency as I am with video latency, though.

1 Like

Sorry, forgot to answer your post (which you’ve now deleted?). I just checked my 8bitdo SFC30 (wired) and Buffalo controllers in USBView. The Buffalo has an 8 ms polling period. The 8bitdo has a 32 ms period, just as you also report.

It’s worth mentioning that the average latency will be half of this, so 4 ms for the Buffalo and 16 ms for the 8bitdo. I’d say it’s pretty unacceptable for a wired controller to cause 1 frame of input lag on average by itself. There’s really no reason for that.

Regarding the fact that there is two USB endpoint descriptors for the 8bitdo: I believe it’s the IN descriptor you should look at. The Buffalo only has the IN descriptor.

So, I guess the takeaway is that you should avoid using USB for the 8bitdo. Bluetooth will have around 8 ms extra input lag over a standard USB controller like the Buffalo, so around 12 ms average total input lag.

2 Likes

So, I guess the takeaway is that you should avoid using USB for the 8bitdo. Bluetooth will have around 8 ms extra input lag over a standard USB controller like the Buffalo, so around 12 ms average total input lag.

So, in general, will using a standard wired USB controller result in less latency than using bluetooth? Intuitively, it seems like that should be the case. Or is this one of those system-dependent things?

To be honest, I don’t know. I have only tested the 8bitdo SFC30 myself. However, I believe the DualShock 4 has lower latency over BT than wired. The DS4 doesn’t use 1000 Hz polling over USB, though, so I think USB could still be slightly faster in the optimal case.

If I were to guess, I’d say that an optimal BT connection should perform more or less the same as a USB connection. It’s of course dependent on how the BT receiver is connected to the system, though. If you have it hanging off of USB, you’ll obviously stack any delay from the BT communication with that of the USB connection…

1 Like