Перейти до вмісту

Вимірювання затримок і PresentMon

На цій сторінці

PCBenchmarkX окремо вимірює внутрішню затримку обробки та затримку виведення кадру. Ці програмні метрики не описують увесь шлях від клацання миші до світіння пікселя на екрані. Повний вимірювальний цикл описано в методиці.

Власний програмний стимул

Section titled “Власний програмний стимул”

Постійний потік генерує сигнали з детермінованими інтервалами 8-12 мс. Якщо Windows дозволяє, він створює очікувальний таймер високої точності; інакше використовує звичайний очікувальний таймер. Очікування події обходиться без безперервного опитування, яке займало б ядро. Глобальна роздільна здатність системного таймера при цьому не змінюється.

Для кожного сигналу логуються запланований строк, пробудження генератора, фактичний сигнал, пробудження отримувача, симуляція, надсилання команд, таймстемпи GPU та події показу. Спільний ідентифікатор кадру пов’язує всі етапи.

Плановий строк → пробудження генератора → сигнал
↓
пробудження отримувача
↓
CPU → команди → GPU
↓
Present → подія виведення

У цих стрічках окремо видно і запізнення таймера, і затримку пробудження отримувача. Початок Core Latency — це фактичний сигнал, тому крок від планового строку до сигналу в цій метриці не враховується.

Постадійна розбивка шляху затримки

Section titled “Постадійна розбивка шляху затримки”

Результат містить постадійну розбивку виміряного шляху latency_path — окремо для Baseline і Loaded. Стадії рахуються від фактичного сигналу:

Стадія Що вимірює
signal_to_consumer_wake від сигналу до пробудження отримувача
cpu_processing CPU-обробку: симуляцію та підготовку даних кадру
cpu_end_to_submit_start паузу від кінця CPU-роботи до початку підготовки надсилання
workload_submit_cpu_span підготовку та запис команд графічного API
submit_start_to_gpu_begin від початку підготовки до початку GPU-роботи; це не чиста затримка черги
gpu_execution саме виконання GPU-роботи, у тактах GPU
presentation spans показ: обгортку Present та інтервали від сигналу і від кінця GPU-роботи до ScreenTime

Кожна стадія подається розподілом зі статистиками та перцентилями. Сегменти рахуються для кожної пари відміток окремо, а не відніманням двох медіан. Якщо кінцева відмітка стадії відсутня або недостовірна, її розподіл залишається порожнім — підставних значень немає. Запізнення таймера (розходження планового строку та фактичного сигналу) записується як окрема діагностика до сигналу і до сумарних значень шляху не входить.

CPU-час записується через QueryPerformanceCounter. Для GPU рушій розміщує дві timestamp query навколо вимірюваної роботи, отримує частоту черги через GetTimestampFrequency і переводить різницю тиків у мілісекунди:

GPU work, ms = (GPU_end − GPU_begin) × 1000 / GPU_frequency

За документацією Microsoft щодо D3D12 timing, timestamp query відображає проходження роботи до кінця конвеєра, а GPU- та CPU-лічильники узгоджуються через GetClockCalibration.

Калібрувальна пара GPU/QPC дозволяє виразити завершення GPU-роботи на тій самій часовій шкалі, що й сигнал:

GPU_completion_QPC = calibration_QPC +
(GPU_end − calibration_GPU) × QPC_frequency / GPU_frequency
Core Latency, ms =
(GPU_completion_QPC − signal_QPC) × 1000 / QPC_frequency

Точність цієї оцінки значною мірою залежить від того, наскільки точно зіставлено годинники CPU та GPU. Вона все одно не покриває USB-шлях миші, час сканування матриці або відгук пікселя. Microsoft окремо описує нюанси високоточних відміток QPC.

Baseline замірює затримку в мінімальній конфігурації цього навантаження. Loaded працює з GPU-навантаженням, відкаліброваним на 8,333333 мс, тобто на обчислювальний бюджет приблизно 120 Гц. Фізичний монітор може мати іншу частоту.

Калібрування змінює складність усередині шейдера в діапазоні 1-4096. Кількість проходів залишається фіксованою: чотири постпроходи. Спочатку підбирається діапазон навколо цільового часу, потім він уточнюється і вибрана конфігурація перевіряється. Щоб зайняти той самий час на швидкій відеокарті, потрібна складніша робота.

У Performance обсяг роботи фіксований. У Loaded Latency навантаження калібрується, щоб час GPU-роботи був близьким на різних відеокартах. Отримані часові відмітки після вимірювання не нормалізуються.

Виведення кадрів тесту затримки йде через окремий презентаційний шлях: безрамкове вікно в режимі flip-discard, максимальна затримка кадру (maximum frame latency) 1, очікуваний об’єкт DXGI і tearing, якщо система його підтримує. Цей шлях відокремлений від фіксованого навантаження продуктивності, яке виконується поза екранним буфером і не викликає Present.

Для подій показу використовується бібліотека PresentMon 2.5.1. Це ETW-проєкт аналізу графічних подій у Windows, описаний його авторами. Procmon / Process Monitor у цьому вимірювальному конвеєрі не застосовується.

PCBenchmarkX піднімає власну сесію збору, відбирає події свого процесу і пов’язує кадри з програмними сигналами. Для цього не потрібна окрема служба і ручний запуск окремого PresentMon.

Зберігаються додаткові інтервали:

  • від сигналу до Present;
  • від Present до ScreenTime;
  • від сигналу до ScreenTime.

ScreenTime — це програмна подія показу кадру; фотодіод для вимірювання світла з екрана не використовується. Метрики показу не входять у PC Score; що в нього входить, описано в розрахунку балів. Підняття сесії ETW може вимагати запуску від імені адміністратора або членства в групі «Користувачі журналу продуктивності». Якщо сесію підняти не вдалося, блоку цієї діагностики не буде, а збій фіксується в результаті явно. Відсутність даних не дорівнює нульовій затримці.

GPU-час PresentMon також зберігається окремо від власного D3D12-часу. Розробники PresentMon відзначають обмеження точності GPU-метрик при HAGS. Тому рушій не підміняє власні GPU timestamps оцінкою з ETW.

У PCBenchmarkX розроблено генератор сигналів, зіставлення етапів кадру, CPU-симуляцію, D3D12-навантаження, калібрування Loaded, порядок повторюваних блоків, збір вимірювань, статистичну обробку та модель балів. QPC і D3D12 надає Windows. Для збору графічних подій через ETW використовується відкритий проєкт PresentMon.

Технічні відомості та зовнішні джерела перевірено 2026-09-20 для рушія 0.5.2.