Benchmark input latency Linux berguna ketika tim perlu membuktikan apakah perubahan pada driver, compositor, game loop, atau wrapper grafis benar-benar menambah atau mengurangi latensi input. Untuk kebutuhan DX, QA, dan CI grafis, tujuannya bukan mencari angka yang “paling kecil” secara absolut, tetapi menghasilkan baseline yang konsisten dan cukup repeatable untuk mendeteksi regresi.

Masalah utamanya adalah input latency di Linux dipengaruhi banyak lapisan: perangkat input, kernel input stack, display server seperti X11 atau Wayland, compositor, VRR, pipeline rendering, sinkronisasi frame, GPU driver, hingga engine atau wrapper seperti DXVK. Karena itu, pengukuran yang berguna untuk engineering harus memisahkan variabel, mendokumentasikan lingkungan uji, dan menerima bahwa hasil CI self-hosted tidak selalu merepresentasikan pengalaman semua pengguna nyata.

Apa yang sebenarnya diukur

Istilah “input latency” sering dipakai terlalu longgar. Untuk validasi teknis, tentukan dulu metriknya agar semua orang di tim membandingkan hal yang sama.

1. Event-to-present

Waktu dari event input diterima aplikasi sampai frame yang merefleksikan input tersebut diajukan ke pipeline present. Ini cocok untuk memeriksa efek perubahan pada event loop, thread model, queueing, atau integrasi DXVK/renderer.

  • Kelebihan: mudah diinstrumentasi di aplikasi atau harness.
  • Kekurangan: belum mencakup scanout monitor dan latensi panel.

2. Event-to-photon perkiraan

Estimasi waktu dari input sampai perubahan tampak di layar. Ini ideal secara UX, tetapi sulit diukur akurat tanpa alat eksternal seperti kamera high-speed atau sensor cahaya.

  • Kelebihan: paling dekat dengan pengalaman pengguna.
  • Kekurangan: sulit diautomasi penuh di CI.

3. Frame pacing dan queue depth

Kadang regresi input bukan berasal dari event handling, melainkan dari bertambahnya antrian frame, blocking di present, atau perubahan sinkronisasi compositor. Karena itu, selain latency, catat juga:

  • waktu frame rata-rata dan persentil,
  • variasi frame time,
  • indikasi queueing/backpressure,
  • mode sinkronisasi yang aktif.

Untuk workflow CI, kombinasi yang paling realistis adalah event-to-present + frame pacing + metadata lingkungan. Jika tersedia alat eksternal di lab, tambahkan pengukuran event-to-photon sebagai validasi periodik.

Variabel yang harus dikontrol

Input latency sangat sensitif terhadap perubahan kecil. Jika variabel tidak dikontrol, hasil benchmark mudah menyesatkan.

Display server: X11 vs Wayland

Perbedaan X11 dan Wayland relevan karena model compositing, scheduling, dan present path berbeda. Dalam beberapa konfigurasi, X11 bisa memberi perilaku yang berbeda dari Wayland terkait fullscreen, tearing policy, frame callback, atau interaksi dengan compositor. Jangan membuat asumsi absolut bahwa salah satu selalu lebih cepat; jadikan keduanya sebagai matriks uji terpisah.

Catat minimal:

  • session type: X11 atau Wayland,
  • nama compositor atau desktop environment,
  • apakah aplikasi berjalan native atau via XWayland,
  • fullscreen eksklusif atau borderless/windowed.

VRR, VSync, dan frame limiting

VRR dapat mengubah hubungan antara input, render completion, dan waktu frame dipresentasikan. VSync dan limiter FPS juga memengaruhi queue depth dan blocking.

Kontrol variabel berikut:

  • VRR aktif/nonaktif,
  • VSync aktif/nonaktif,
  • frame limiter internal engine aktif/nonaktif,
  • refresh rate monitor yang digunakan.

Jika tujuan Anda adalah regression check, jangan mencampur hasil VRR ON dan VRR OFF dalam baseline yang sama. Simpan sebagai profil uji yang berbeda.

Driver, kernel, CPU governor, dan GPU clocks

Regresi kecil bisa tertutup oleh variasi frekuensi CPU/GPU. Untuk repeatability, upayakan lingkungan yang stabil:

  • catat versi kernel dan driver GPU,
  • gunakan governor CPU yang konsisten,
  • hindari beban latar belakang yang berubah-ubah,
  • pastikan thermal throttling tidak terjadi selama uji.

Di mesin CI self-hosted, idealnya node benchmark didedikasikan untuk beban ini, bukan runner bersama dengan job lain.

Wrapper grafis seperti DXVK

Jika aplikasi Windows dijalankan melalui Wine dan DXVK, maka jalur input dan rendering berubah dibanding native Linux. DXVK bisa memengaruhi CPU overhead, shader compilation behavior, present model, dan interaksi dengan driver Vulkan. Perlakukan ini sebagai dimensi pengujian tersendiri:

  • native renderer,
  • Wine tanpa DXVK jika relevan,
  • Wine + DXVK,
  • opsi render backend lain jika aplikasi mendukung.

Tujuan benchmarking bukan membuktikan DXVK “lebih cepat” secara umum, melainkan mendeteksi perubahan relatif pada konfigurasi yang memang Anda dukung.

Desain skenario uji yang repeatable

Benchmark yang baik harus mengurangi noise dan menguji jalur yang paling berisiko mengalami regresi.

Skenario 1: Harness sintetis untuk event-to-present

Ini skenario paling cocok untuk CI. Buat aplikasi kecil atau mode benchmark di aplikasi utama yang:

  1. menerima event input sintetis atau nyata,
  2. mengubah state visual deterministik, misalnya warna kotak dari hitam ke putih,
  3. mencatat timestamp saat event diterima,
  4. mencatat timestamp saat frame perubahan diajukan untuk present.

Jika Anda mengontrol source code aplikasi, instrumentasi langsung jauh lebih andal daripada menebak dari luar.

Skenario 2: Camera-assisted lab test

Untuk validasi berkala, gunakan kamera high-speed yang merekam LED/sinyal input dan perubahan layar. Ini tidak selalu cocok untuk CI otomatis, tetapi penting sebagai kalibrasi bahwa metrik internal Anda masih berkorelasi dengan hasil dunia nyata.

Skenario 3: Gameplay loop atau interaction trace

Untuk engine, emulator, atau game/tool interaktif, uji juga skenario yang lebih mendekati penggunaan nyata:

  • gerakan kamera konstan,
  • spam tombol terjadwal,
  • perubahan UI cepat,
  • beban CPU/GPU yang menyerupai kasus produksi.

Jangan hanya mengukur scene idle. Banyak regresi input baru muncul ketika queue render penuh atau shader sedang dikompilasi.

Durasi dan jumlah sampel

Gunakan beberapa putaran uji, bukan satu kali eksekusi. Misalnya:

  • warm-up untuk mengurangi efek inisialisasi, cache, dan shader compilation awal,
  • beberapa run identik,
  • laporkan median dan persentil tinggi, bukan hanya rata-rata.

Median membantu melihat perilaku normal, sedangkan persentil seperti p95 atau p99 membantu menangkap spike latency yang dirasakan pengguna.

Instrumentasi dan pencatatan hasil

Bagian terpenting dari benchmark input latency Linux adalah format data yang konsisten. Tanpa ini, sulit membandingkan baseline dari waktu ke waktu.

Timestamp yang dicatat

Minimal, simpan timestamp monotonic untuk titik-titik berikut:

  • t_input_received: event diterima aplikasi,
  • t_simulation_updated: state aplikasi berubah karena input, bila relevan,
  • t_render_submitted: command rendering untuk frame perubahan dikirim,
  • t_present_called: present/swap dipanggil,
  • frame_id dan input_id untuk korelasi.

Jangan gunakan timestamp wall clock. Gunakan jam monotonic resolusi tinggi agar tidak terpengaruh perubahan waktu sistem.

Contoh format hasil JSON

{
  "test_name": "input-latency-harness",
  "session": "wayland",
  "compositor": "example-compositor",
  "renderer": "vulkan",
  "wrapper": "dxvk",
  "vsync": true,
  "vrr": false,
  "fullscreen": true,
  "refresh_hz": 144,
  "kernel": "6.x",
  "gpu_driver": "vendor-driver",
  "runs": [
    {
      "run_id": 1,
      "samples": 500,
      "event_to_present_median_ms": 12.4,
      "event_to_present_p95_ms": 18.1,
      "frame_time_p95_ms": 9.3
    }
  ]
}

Angka di atas hanya contoh struktur, bukan nilai referensi.

Metadata yang wajib disimpan

  • commit aplikasi atau engine,
  • commit konfigurasi benchmark,
  • hostname runner,
  • session type, compositor, display mode,
  • driver, kernel, backend render, wrapper,
  • resolusi, refresh rate, VRR/VSync,
  • mode daya atau governor bila relevan.

Metadata ini penting saat hasil berubah karena lingkungan, bukan karena perubahan kode.

Implementasi otomasi lokal dan CI self-hosted

CI untuk benchmark grafis sebaiknya dianggap sebagai signal system, bukan oracle mutlak. Fokusnya adalah mendeteksi perubahan yang mencurigakan secara konsisten.

Prinsip runner benchmark

  • Gunakan runner self-hosted dengan GPU fisik.
  • Dedikasikan runner untuk job benchmark, hindari workload campuran.
  • Kunci konfigurasi display dan session sebisa mungkin.
  • Jalankan benchmark pada waktu sistem relatif tenang.

Contoh skrip benchmark sederhana

#!/usr/bin/env bash
set -euo pipefail

OUT_DIR=${1:-artifacts}
mkdir -p "$OUT_DIR"

export APP_BENCHMARK_MODE=1
export APP_BENCHMARK_OUTPUT="$OUT_DIR/result.json"

# Sesuaikan dengan launcher aplikasi Anda.
./my_app --scenario input-latency --samples 500 --warmup 100

python3 scripts/evaluate_latency.py \
  --input "$OUT_DIR/result.json" \
  --baseline benchmarks/baseline-wayland-vrr-off.json \
  --output "$OUT_DIR/evaluation.json"

Skrip ini memisahkan tiga tahap: menjalankan aplikasi, menghasilkan data mentah, lalu mengevaluasi terhadap baseline.

Contoh evaluasi regresi

Daripada memakai satu angka tunggal, lebih aman mendefinisikan aturan sederhana seperti:

  • gagal jika median event-to-present naik lebih dari ambang tertentu,
  • gagal jika p95 naik tajam walau median stabil,
  • beri peringatan jika frame pacing memburuk tetapi belum melewati ambang gagal.
import json
import sys

current = json.load(open(sys.argv[1]))
baseline = json.load(open(sys.argv[2]))

cur = current["runs"][0]
base = baseline["runs"][0]

median_delta = cur["event_to_present_median_ms"] - base["event_to_present_median_ms"]
p95_delta = cur["event_to_present_p95_ms"] - base["event_to_present_p95_ms"]

fail = False
if median_delta > 2.0:
    fail = True
if p95_delta > 4.0:
    fail = True

print(json.dumps({
    "median_delta_ms": median_delta,
    "p95_delta_ms": p95_delta,
    "fail": fail
}, indent=2))

sys.exit(1 if fail else 0)

Ambang di atas hanya contoh. Pilih berdasarkan variasi alami runner Anda. Jika noise baseline besar, ambang terlalu ketat hanya akan menghasilkan false positive.

Strategi baseline yang sehat

Jangan simpan satu baseline global untuk semua mesin. Buat baseline per profil uji, misalnya:

  • X11 + VSync ON + VRR OFF,
  • Wayland + VSync ON + VRR OFF,
  • Wayland + VRR ON,
  • Wine + DXVK,
  • native Vulkan/OpenGL bila relevan.

Setiap baseline harus dikaitkan ke runner dan konfigurasi tertentu. Saat driver atau kernel sengaja diperbarui, lakukan re-baseline setelah validasi manual.

Matriks uji yang masuk akal

Tim sering gagal karena mencoba menguji terlalu banyak kombinasi sekaligus. Mulai dari matriks kecil yang mewakili risiko tertinggi.

Minimum viable matrix

  • 1 session X11 atau Wayland yang paling umum dipakai pengguna target,
  • 1 konfigurasi tanpa VRR,
  • 1 mode fullscreen,
  • 1 backend render utama,
  • 1 runner GPU yang stabil.

Matriks lanjutan

  • X11 vs Wayland,
  • VRR ON vs OFF,
  • native vs DXVK,
  • fullscreen vs borderless,
  • beban ringan vs beban berat GPU.

Jika sumber daya CI terbatas, prioritaskan kombinasi yang paling sering berubah atau paling sering menimbulkan bug pada histori proyek Anda.

Kesalahan umum dan cara debugging

Mencampur noise lingkungan dengan regresi kode

Jika hasil fluktuatif, periksa proses latar belakang, thermal throttling, perubahan refresh rate, atau migrasi session dari native Wayland ke XWayland tanpa disadari.

Mengandalkan rata-rata saja

Rata-rata bisa terlihat baik walau spike latency memburuk. Selalu lihat median dan persentil tinggi.

Tidak memisahkan warm-up

Shader compilation, cache loading, dan inisialisasi pipeline bisa merusak hasil jika digabung dengan steady-state measurement.

Menganggap CI mewakili semua pengguna

Runner CI biasanya jauh lebih terkontrol daripada perangkat pengguna. Hasilnya sangat bagus untuk deteksi regresi internal, tetapi tidak cukup untuk menyimpulkan pengalaman universal di berbagai GPU, monitor, refresh rate, atau compositor.

Tidak mengikat hasil ke konfigurasi display

Perubahan kecil seperti VRR aktif, mode fullscreen berbeda, atau refresh rate monitor berubah dapat memengaruhi hasil signifikan. Tanpa metadata, angka benchmark kehilangan konteks.

Kapan hasil CI tidak cukup

Ada kondisi ketika benchmark otomatis harus dilengkapi pengujian manual atau lab:

  • perubahan besar pada compositor atau display stack,
  • migrasi X11 ke Wayland atau sebaliknya,
  • perubahan kebijakan VSync/VRR,
  • laporan pengguna tentang “terasa lebih lambat” tetapi CI tidak menunjukkan regresi,
  • integrasi wrapper baru seperti DXVK atau perubahan present mode.

Pada situasi ini, lakukan verifikasi dengan alat eksternal atau uji pada beberapa kelas perangkat nyata. Metrik internal tetap berguna, tetapi jangan dijadikan satu-satunya sumber kebenaran.

Rekomendasi workflow praktis

  1. Buat harness input latency yang mengukur event-to-present dengan timestamp monotonic.
  2. Definisikan profil uji terpisah untuk X11/Wayland, VRR, VSync, fullscreen, dan DXVK bila relevan.
  3. Jalankan warm-up lalu beberapa run identik.
  4. Simpan median, p95, frame pacing, dan metadata lingkungan dalam JSON artifact.
  5. Bandingkan hasil dengan baseline per runner dan per profil.
  6. Gunakan ambang regresi yang realistis berdasarkan variasi historis runner.
  7. Validasi berkala dengan pengujian lab atau perangkat nyata untuk memastikan korelasi dengan UX.

Dengan pendekatan ini, benchmark input latency Linux menjadi alat engineering yang berguna untuk validasi DX dan CI grafis: bukan untuk mengklaim angka absolut, tetapi untuk menangkap perubahan yang benar-benar penting setelah update driver, perubahan compositor, modifikasi game loop, atau integrasi wrapper grafis.