跳转到内容

延迟测量与 PresentMon

本页内容

PCBenchmarkX 单独测量内部处理延迟和帧输出延迟。这些软件指标并不描述从鼠标点击到屏幕像素发光的完整路径。完整的测量循环见方法说明。

恒定流以确定性间隔 8-12 毫秒生成信号。如果 Windows 允许,它会创建一个高精度等待计时器;否则使用普通等待计时器。事件等待无需持续轮询,因为持续轮询会占用内核。系统计时器的全局分辨率不会因此改变。

对每个信号都会记录计划期限、生成器唤醒、实际信号、接收方唤醒、模拟、命令提交、GPU 时间戳和显示事件。统一的帧标识符将所有阶段关联起来。

计划期限 → 生成器唤醒 → 信号
↓
接收方唤醒
↓
CPU → 命令 → GPU
↓
Present → 输出事件

在这些时间线中,可以分别看到计时器迟延和接收方唤醒延迟。Core Latency 的起点是实际信号,因此从计划期限到信号这一步不计入该指标。

结果包含所测路径 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 使用校准到 8,333333 毫秒的 GPU 负载,即约 120 Hz 的计算预算。物理显示器可能具有不同的刷新率。

校准在 1-4096 范围内改变着色器内部的复杂度。通道数保持固定:四个后处理通道。首先围绕目标时间选取范围,然后对其进行细化并验证所选配置。要在快速显卡上占用相同时间,需要更复杂的工作。

在 Performance 中工作量固定。在 Loaded Latency 中,负载经过校准,使 GPU 工作时间在不同显卡上接近。测量后获得的时间标记不会进行归一化。

延迟测试的帧输出通过单独的呈现路径进行:flip-discard 模式下的无边框窗口、最大帧延迟(maximum frame latency)为 1、DXGI 等待对象,以及系统支持时的 tearing。该路径与固定的性能负载分离,后者在屏幕缓冲区之外执行,不会触发 Present。

显示事件使用 PresentMon 2.5.1 库。这是一个 Windows 图形事件分析的 ETW 项目,由其作者描述。此测量管线中不使用 Procmon / Process Monitor。

PCBenchmarkX 启动自己的采集会话,筛选自身进程的事件,并将帧与软件信号关联。这不需要单独的服务,也不需要手动启动单独的 PresentMon。

会保存额外的间隔:

  • 从信号到 Present;
  • 从 Present 到 ScreenTime;
  • 从信号到 ScreenTime。

ScreenTime 是帧显示的软件事件;不使用光电二极管测量屏幕发出的光。显示指标不计入 PC Score;计入的内容见分数计算。启动 ETW 会话可能需要以管理员身份运行或属于“Performance Log Users”组。如果会话无法启动,则不会有该诊断块,且失败会明确记录在结果中。数据缺失不等于零延迟。

PresentMon 的 GPU 时间也与自有 D3D12 时间分开存储。PresentMon 的开发者指出了 HAGS 下 GPU 指标精度的限制。因此引擎不会用 ETW 的估计值替代自有 GPU timestamps。

PCBenchmarkX 中开发了信号生成器、帧阶段关联、CPU 模拟、D3D12 负载、Loaded 校准、重复块的顺序、测量采集、统计处理和分数模型。QPC 和 D3D12 由 Windows 提供。通过 ETW 采集图形事件使用了开源项目 PresentMon。

技术信息和外部来源已针对引擎 0.5.2 于 2026-09-20 核实。