Linux 系统输入延迟测量:X11 与 Wayland、VRR 以及 DXVK 的对比
Measuring Input Latency on Linux: X11 vs. Wayland, VRR, and DXVK

原始链接: https://marco-nett.de/blog/measuring-input-latency-on-linux-x11-vs-wayland-vrr-dxvk/

为了确定 Linux 游戏优化是真正降低了输入延迟还是仅仅是心理作用,作者制作了一款定制硬件设备——将光传感器与微控制器结合——来测量端到端的系统延迟。 作者在 500Hz 高刷新率环境下测试了《Diabotical》,对比了 X11、Wayland、VRR 和 `dxvk-low-latency` 的表现。主要研究结果如下: * **避免使用 XWayland:** 通过 XWayland 运行游戏会带来明显的延迟(3.13ms),超过了所有其他变量的总和。 * **Wayland 与 X11:** 虽然 X11 在技术上更快,但差距微乎其微(0.14–0.22ms),反驳了关于 Wayland 本身“迟滞”的说法。 * **VRR 很重要:** 可变刷新率(VRR)持续改善了延迟并稳定了帧分布。 * **DXVK 的优势:** `dxvk-low-latency` 分支在限制帧率的情况下提供了小幅提升,而在不限帧的情况下,它通过防止渲染队列堆积和优化帧平滑度表现出色。 最终,该研究证实,虽然各项独立优化带来的提升很小(总计约 0.72ms),但最关键的因素是避开 XWayland。作者已将所有原理图和数据发布在 GitHub 上,供那些希望验证自己系统的人参考。

*marco-nett.de* 最近的一篇文章通过数据驱动的方式,调查了 Linux 桌面环境中的输入延迟问题,并对比了 X11、Wayland 以及可变刷新率(VRR)和 DXVK 等技术。 这篇文章在 Hacker News 上引起了极大关注。读者们称赞作者进行了实证测试,而非依赖道听途说。讨论凸显了一个常见的争议点:尽管一些用户推崇 Wayland 的性能(特别是在搭载 AMD GPU 的 KDE Plasma 等现代硬件上),但也有人指出,通过 XWayland 运行老旧的 X11 游戏时,延迟可能会增加。评论者认为,社区中关于 Wayland “迟钝”的固有印象,可能正是源于这些特定的兼容层。这进一步凸显了作者通过技术测量来厘清此类常见用户体验的价值。
相关文章

原文

Two years ago, I switched to Linux on my gaming PC. People kept telling me that it could perform way better than Windows when it comes to FPS, frame pacing and input latency, and when I tried it out, it did feel a lot better.

The internet is full of advice on optimizing Linux for gaming:

I play competitive FPS games, so low latency, consistent frame times and high FPS matter to me. On Linux, there are countless settings to tweak for this (magic env vars, gamescope, gamemode, even more DXVK forks, and so on).

But it always bothered me that I did not have a reliable way to verify whether something actually lowered the system latency or if it was just snake oil, a placebo effect, or actually worse without me realizing it.


The idea is simple: Strap a device with some kind of light sensor onto a monitor and connect it via USB to the PC to simulate mouse clicks. On click, measure the time between the click and the moment the light sensor detects a change on the screen.

This way, you measure the end-to-end system latency.

Latency pipeline diagram: stages from mouse input through CPU, render-queue, GPU, compositing and scanout to the display, grouped into peripheral, PC, and display latency; together forming the end-to-end system latency.
© NVIDIA has a picture that summarizes this quite nicely.

While there are now a couple of open source devices like this available, like m2p-latency or the Open-Source-LDAT, when I started this side project, there was just the OSLTT, and knowing nothing about hardware, I was happy to study its schematics and loosely base my design on it.

But finishing my project just this month, I ended up integrating a lot of ideas from the other two projects as well.

To make a long story short, I learned a lot about microcontrollers, soldering, Arduino firmware development, integration time, transimpedance amplifiers, KiCad (just a little) and enclosure design.

Here’s what I landed on:

  • An Adafruit QT Py RP2040 acts as a USB HID mouse with 1000 Hz polling rate and fires a click.
  • The moment the click is sent, it starts collecting samples from the photodiode (every ~24 µs).
  • 12,000 samples per click are streamed over serial to the host and logged to a CSV.
  • Based on the samples, a tool on the host establishes a per-click baseline, then finds the first sample that deviates a certain amount from the baseline.
  • Because the time it takes to collect 12k samples is fixed, it can now calculate the time between sending the click and detecting a brightness change on the screen.

I wanted to test three different things.

Display server (X11 vs Native Wayland)

A lot of people still use X11 over Wayland because Wayland is said to have much worse input lag. Just searching for it, there are a lot of people complaining that Wayland “feels off”.

VRR (on vs off)

Variable Refresh Rate / G-Sync / FreeSync / Whatever you want to call it. Also highly debated.

DXVK low-latency fork (on vs off)

Referred to as dxvk-low-latency or low-latency from now on.
The maintainer of this fork, netborg, put a lot of effort into developing this frame pacer and it recently got integrated into the official proton-cachyos package, enabled via the env var PROTON_DXVK_LOWLATENCY=1. This fork’s promises were one of the deciding factors in me wanting to try out desktop Linux again.

Bonus: dxvk-low-latency vs default dxvk uncapped

The biggest advantages a frame pacer like dxvk-low-latency brings are to absorb frame time fluctuations and to prevent render-queue buildup.
With the testing method I used (a static in-game scene, see below for more), there were no frame time fluctuations to observe, as all tests produced purely CPU-bound scenarios. But this mostly does not reflect a real gaming session, where frame times can fluctuate because of what happens in-game or outside the game (e.g. other processes using resources).

So to show the pacer at work I added two uncapped test cases.

Bonus: Native Wayland vs XWayland

I ran all Wayland test cases via native Wayland (PROTON_ENABLE_WAYLAND=1) as I was already aware that XWayland would introduce lag. But for the sake of comparison, I added two XWayland test cases (only with VRR off).


Hardware
AMD Ryzen 7 5800X3D
NVIDIA GeForce RTX 4070 SUPER
2x8 GB DDR4 at 3200 MHz
MSI MAG 272QP QD-OLED X50 at 2560×1440 / 500 Hz
MSI B450 GAMING PRO CARBON AC

Only one display was connected during the tests.


SoftwareVersion
CachyOS-
Kernel7.1.3-2-cachyos
NVIDIA driver610.43.03-1
KDE Plasma6.7.2-1.1
xorg-server21.1.24-1.1
proton-cachyos-native1:11.0.20260602-3
dxvk (via proton-cachyos)3.0

The default CachyOS kernel scheduler was used.


System Settings

  • 500 Hz refresh rate in system settings
  • Flip mode on X11: Enabled via nvidia-settings
  • Flip mode on Wayland: Confirmed to be enabled (see below how)
  • VRR on X11: Enabled via nvidia-settings (changing this requires a reboot)
  • VRR on Wayland: Enabled via KDE Settings Menu (no reboot needed)

Flip mode (or “direct scanout”) vs Blit mode (compositing) on Wayland: There is no setting for it. The compositor decides by itself whether it composites a frame or uses direct scanout.
To make sure the game is running in flip mode: Open “KWin Debug Console” (it’s a GUI tool) and in the “Effects” tab, enable showcompositing. Then make sure the game is fully focused and the only thing on screen in fullscreen mode. If there’s no red border visible around the edges of the game, it’s in Flip mode.

dxvk

To make the comparison fair, an optimized dxvk.conf was used depending on the scenario:

  • If VRR was disabled, dxgi.maxFrameRate = 500 was set (FPS capped at the screen’s refresh rate)
  • If VRR was enabled and dxvk-low-latency was disabled, dxgi.maxFrameRate = 497 was set (FPS capped slightly below screen refresh rate)
  • If VRR was enabled and dxvk-low-latency was enabled, the following was used to utilize the low latency VRR frame pacing:
dxgi.maxFrameRate = 480
dxvk.lowLatencyOffset = 70
dxvk.framePace = "low-latency-vrr-500"
dxvk.lowLatencyAllowCpuFramesOverlap = False

In all cases, d3d11.cachedDynamicResources = "c" was set.


The game I used is Diabotical, a DirectX 11 game, launched through Heroic with Proton.

Game settings

  • Native screen resolution
  • 100% render scale
  • Vsync off
  • Every other video setting as low as possible

There is a hidden command that hides the UI for a short amount of time. Binding that command to left click (/bind mouse_left testlatency) and setting up a HUD that would display a large white box, I was able to produce large brightness differences on click.

Methodology

  • Close unnecessary software.
  • Launch the game.
  • Start a local match server (same mode and map every time).
  • Move to a specific spot, put the mouse onto a specific landmark.
  • Run the test case iteration (100 clicks, runs for about 2 minutes).
  • Once the test is done, start the next test case iteration (3 in total).
  • In-game conditions: No bots, no other players, no movement, no round restarts. It is basically just a static scene that will stay like this indefinitely.
  • System conditions: During testing, no other significant processes should be running on the system.
  • The measuring device remained in the same position (see the video) across all tests.

click2photon latency: X11 / Wayland, VRR, low-latencyDiabotical, 500 Hz QD-OLED, RTX 4070 SUPER, 300 clicks per case.

Every capped test case held its frame rate cap stable during testing and the game remained CPU-bound throughout.

The data seems clean: No test case produced wild outliers and every case produced a bell-shaped distribution, roughly 2 to 3 ms wide between p5 and p95.

Three things jump out:

  • The 8 main cases all land within 0.72 ms of each other (medians from 4.21 ms to 4.93 ms).
  • XWayland adds 3.13 ms on top of its native Wayland equivalent (8.06 ms vs 4.93 ms median).
  • In the uncapped cases, the dxvk fork managed to reduce latency by 0.84 ms.

Here is the fastest case:

Latency distribution: fastest case (X11, VRR, low-latency)

So, does X11 have lower latency than Wayland?
Yes, but nowhere near enough to explain why Wayland is generally perceived as much worse than X11.

ConfigurationX11WaylandDifference
low-latency + VRR4.21 ms4.38 ms+0.17 ms
low-latency4.64 ms4.83 ms+0.19 ms
VRR4.45 ms4.67 ms+0.22 ms
plain4.79 ms4.93 ms+0.14 ms

X11 wins in each scenario, but it is just a 0.14 to 0.22 ms difference.
The distribution is very similar:

Latency distribution: plain X11 vs plain Wayland

---https://news.ycombinator.com/

VRR has the biggest impact across the pairings: enabling it is 0.26 to 0.45 ms faster than leaving it disabled.

ConfigurationVRR offVRR onDifference
X11, low-latency4.64 ms4.21 ms-0.43 ms
X114.79 ms4.45 ms-0.34 ms
Wayland, low-latency4.83 ms4.38 ms-0.45 ms
Wayland4.93 ms4.67 ms-0.26 ms

It also flattens the distribution: the p95-p5 spread is 2.1 to 2.2 ms in the VRR cases versus 2.6 to 3.0 ms without VRR.

Latency distribution: VRR on vs VRR off (Wayland, low-latency)

That’s consistent with how VRR works: frames scan out when they are ready instead of waiting for the next scanout slot.


In the capped test cases, the difference is small but consistent and of about the same magnitude as X11 vs Wayland. Where the difference between Wayland and X11 is on average 0.18 ms, using dxvk-low-latency is on average 0.20 ms faster.

Configurationlow-latency offlow-latency onDifference
X11, VRR4.45 ms4.21 ms-0.24 ms
X114.79 ms4.64 ms-0.15 ms
Wayland, VRR4.67 ms4.38 ms-0.29 ms
Wayland4.93 ms4.83 ms-0.10 ms

In the uncapped test cases, we can get an idea of where the real strength of dxvk-low-latency lies: smoothing out uneven frame pacing and preventing render-queue buildup.
The pacer does this by making sure the GPU is never fully utilized, so the game is always close to GPU-bound, but never entirely. This could be observed in the test runs, where GPU utilization was at 95-97% with dxvk-low-latency and at 100% without it. This comes at a small price in the form of FPS.

Dimensionlow-latency offlow-latency onDifference
Latency5.27 ms4.43 ms-0.84 ms
FPS715670-45
Latency distribution: uncapped, DXVK low-latency on vs off (X11)

All Wayland tests so far ran the game natively via PROTON_ENABLE_WAYLAND=1 (or the “Enable Wine-Wayland (Experimental)” toggle in Heroic Launcher). Turning that off makes the game run through XWayland instead, and that’s where it gets bad.

Configurationnative WaylandXWaylandDifference
low-latency4.83 ms5.95 ms+1.12 ms
plain4.93 ms8.06 ms+3.13 ms

Without dxvk-low-latency, XWayland adds 3.13 ms of latency to the measurement. That is more than all the other effects I measured combined. It’s also not occasional bad frames dragging the average up; the entire distribution shifts:

Latency distribution: native Wayland vs XWayland

Notably, adding dxvk-low-latency to the XWayland test lowered the latency by 2.11 ms, the biggest gain across all scenarios.


These results were produced under best-case conditions (stable FPS at cap, CPU-bound) and are of course specific to my hardware and chosen software stack.

The absolute numbers will look different on other setups, but the gains and losses from each test case should roughly transfer. On a lower refresh rate display, the gains from VRR and the low-latency pacer would likely be even larger.

Avoid XWayland

It added 3.13 ms of latency, more than all other effects combined.

Wayland is close, but X11 still wins

Though only by 0.14 to 0.22 ms. Given there are efforts to optimize KWin, this gap will likely close sooner rather than later. And who knows, other Wayland compositors might already be better.

VRR has the biggest effect

VRR was faster in every pairing (0.26 to 0.45 ms) and also flattened the latency distribution.

dxvk-low-latency is a win across the board

0.10 to 0.29 ms in capped scenarios is a nice boost, but the real strength of the fork shows in the uncapped test case, where it gained 0.84 ms over default dxvk.
Additionally, in scenarios where XWayland can’t be avoided, it recovered a full 2.1 ms.

Conclusion

Not factoring in XWayland, applying every optimization (X11, VRR, low-latency) compared to a default setup (which, on a modern Linux system, I assume is plain Wayland) moved the median down by 0.72 ms.
That does not sound like a lot, but the raw latency does not tell the whole story as VRR additionally reduces latency jitter, and dxvk-low-latency’s pacer is great at smoothing out real-world scenarios where frame time dips and GPU-bound situations occur.


David Ramiro built his m2p-latency and compared X11 vs Wayland in his article Building an Input Latency Meter (Because ‘Wayland Feels Off’ Isn’t a Metric) as well, coming to similar conclusions:
Native Wayland is on par with native X11 (all tied at ~7 ms), while XWayland roughly doubled the latency in his tests.

farnoy did extensive testing with the Open-Source-LDAT in his post Linux latency measurements and compositor tuning, also concluding that XWayland should be avoided.

My side quest measuring input latency with VK_EXT_present_timing by Themaister describes a different method of measuring latency without any external hardware by injecting input via /dev/uinput and detecting the resulting image change on the GPU.
This does not measure end-to-end system latency, but removes USB and display latency from the equation, narrowing it down to only measuring PC latency. The project can be found on GitHub.

联系我们 contact @ memedata.com