Якуб Оконьский (Jakub Okonski) выяснил, почему в KDE Plasma игры и приложения отзываются на действия мыши медленнее, чем в Windows 11, и подготовил серию патчей для композитора KWin. Задержку от нажатия кнопки до изменения изображения на экране он измерял микроконтроллером Teensy с датчиком освещённости, прижатым к дисплею. Главным источником потерь оказался завышенный прогноз времени сборки кадра: при фактических 2,06 мс медианная оценка достигала 11,35 мс. После правок минимальная задержка вывода опустилась примерно до 3 мс. Патчи планируется отправить в основную ветку KWin в ближайшие недели, поэтому в Plasma 6.7, выходящую , они не войдут.

KWin — оконный менеджер и композитор Wayland в KDE Plasma. Он собирает изображения окон в единый кадр и передаёт его подсистеме вывода, поэтому от его планирования зависит задержка всех приложений рабочего стола.
Teensy в роли мыши и две системы на NVIDIA Ada
Плата Teensy подключается к компьютеру как обычная USB-мышь, а датчик фиксирует момент, когда пиксели меняют яркость. Прошивка основана на открытой реализации LDAT с небольшими доработками и записывает сотни замеров в CSV-файл без участия человека.
Замеры выполнялись на настольном компьютере и ноутбуке с видеокартами NVIDIA поколения Ada и процессорами AMD Zen 4. На обеих машинах использовалась почти одинаковая конфигурация NixOS с KDE Plasma 6.6.4 в сеансе Wayland, Proton-GE 10-33, MangoHud 0.8.2 для позднего ограничения частоты кадров и драйвером NVIDIA 595.58.03, а рядом — свежая Windows 11. Изображение выводилось на телевизор LG C1 при 120 Гц по HDMI, а настройки игр подбирались так, чтобы система стабильно выдавала 120 кадров в секунду и проявлялись эффекты очередей в программном стеке.
Фоновое окно Zed и настройки телевизора
Первая загадка возникла ещё на проверочных тестах: настольный компьютер отставал от ноутбука минимум на 3 мс при одинаковом программном окружении, а на чистой учётной записи разница исчезала. Перебор приложений выявил виновника: открытое окно редактора Zed, даже простаивая в фоне, увеличивало задержку всех остальных окон. Полноэкранных игр эффект не касался.
Из настроек телевизора заметнее всего повлияла вставка чёрного кадра (Black Frame Insertion): она добавила ровно один кадр задержки, то есть около 8,3 мс при 120 Гц. Переключение входа в режим PC, блокирующее часть настроек изображения, на замеры не повлияло, а включение HDR дало небольшой, но измеримый эффект.
В играх картина различалась. В Doom Eternal на Vulkan платформы шли почти вровень, у Linux лишь шире оказался хвост распределения начиная с 75-го перцентиля; сама игра при этом запускалась только через XWayland. В Borderlands 3 задержка под Windows была стабильно ниже, особенно при включённой вертикальной синхронизации, однако запуск через PROTON_ENABLE_WAYLAND=1 — родной сеанс Wayland вместо XWayland — возвращал потерянные миллисекунды. Direct3D 12 во всех замерах уступал Direct3D 11 на обеих операционных системах, а из переменных окружения эффект дала только VKD3D_SWAPCHAIN_LATENCY_FRAMES=1, но и с ней разрыв между двумя версиями API сохранялся. Сильнее любых переключателей помогало ограничение частоты кадров чуть ниже частоты обновления: при 117 кадрах в секунду на 120-герцевом экране кадры не копятся в очереди показа.
VKD3D-Proton — транслятор вызовов Direct3D 12 в Vulkan из состава Proton. Переменные окружения вида VKD3D_* меняют его поведение без правки самих игр.
Откуда в KWin лишние 9 миллисекунд
Чтобы понять разницу с Windows, автор добавил в KWin инструментирование и проанализировал журнал встроенного профилировщика, включаемого переменной KWIN_LOG_PERFORMANCE_DATA=1. Медианный прогноз времени сборки кадра составил 11,35 мс при фактических 2,06 мс — разница в 9,23 мс уходила прямиком в задержку. Когда прогноз не помещается в текущий кадр, отрисовка переносится на следующий, и приложение пропускает ближайшую смену изображения.
Та же механика объяснила эффект Zed: окно, выводящее новый кадр каждые 8,3 мс, полностью занимает планировщик композитора, интервал, отведённый остальным клиентам, сужается, и они промахиваются мимо ближайшего вывода кадра. Архитектурной проблемой автор это не считает — в алгоритме планирования предусмотрено время, за которое другие окна успевают присоединиться к кадру, но запасы выбраны чрезмерно осторожно.
Источников лишнего запаса набралось три. Первый — фиксированная миллисекунда «на неточности планировщика»: таймеры Qt на Unix округляют любой интервал вверх до целой миллисекунды, точнее проснуться через них нельзя. Автор написал собственный таймер на основе timerfd, подключил его к циклу событий через QSocketNotifier и получил отклонение пробуждения от цели в 51 мкс в 99-м перцентиле.
Второй источник — запас безопасности перед передачей готового кадра видеоподсистеме, в среднем около 1,46 мс. На свежих драйверах NVIDIA его удалось урезать через переменную KWIN_DRM_OVERRIDE_SAFETY_MARGIN до значения -150 микросекунд — отрицательные числа здесь разрешены и уменьшают вклад остальных слагаемых; эффективный резерв при этом составил порядка 0,3 мс. Третий — нижний порог в 2 мс при оценке времени отрисовки кадра: на RTX 4090 даже в энергосберегающем состоянии P8 реальная медиана составляет 0,36 мс. Вместо жёсткого порога автор завёл кольцевой буфер замеров за последние 512 кадров и заставил оценку быстрее опускаться к 95-му перцентилю фактического времени.
Фиксированные константы особенно дороги на быстрых экранах: при 360 и 540 Гц одна миллисекунда занимает 36% и 54% длительности кадра соответственно.
Минимальная задержка после патчей — около 3 мс
Под конец испытаний плата Teensy вышла из строя, поэтому итоговые сравнения построены на внутренней метрике «от ввода до вывода кадра» из инструментированного KWin. По архивным записям она хорошо согласуется с показаниями датчика: коэффициент R&襪 в каждом прогоне составил не менее 94%.
После патчей минимальная задержка вывода без фоновой нагрузки опустилась до 3 мс и ниже — ровно к расчётному пределу, выведенному в начале разбора. Восстановилась и справедливость планирования: запущенная в фоне тестовая программа eglgears больше не ухудшает отклик соседних окон.
Наибольший выигрыш получают оконные игры и приложения. Полноэкранным играм с вертикальной синхронизацией и прямым выводом (direct scanout) правки экономят порядка миллисекунды. В сценариях с VRR или с разрешёнными разрывами кадра задержка не изменится, пока частота кадров не превышает частоту обновления экрана. Минимальные значения улучшились на 1,1–1,2 мс, тогда как разрыв между Linux и Windows в лучших замерах с VRR держался около 4 мс.
Заключение
Патчи планируется отправить в основную ветку KWin в ближайшие недели; до этого автор будет ежедневно работать на исправленной сборке и следить за долей опоздавших кадров, чтобы снижение задержки не обернулось потерей плавности. Он также присматривается к расширению Vulkan FIFO_LATEST_READY_EXT против очередей при упоре в частоту обновления, к протоколу commit-timing и к возможностям, которые откроет переход композитинга KWin на Vulkan. Подробный разбор с графиками опубликован в блоге автора.