游戏卡顿白皮书 › L2 客户端操作系统与设备
定时器精度 Timer resolution (Windows 15.6ms)
原因 ID co-timer · 主责 研发团队·客户端开发
在含图示和实验的完整版中打开此卡片 →
Windows 默认定时器以 15.6 ms 为单位,“只休眠 1 ms”实际要等到下一个定时器周期,最长会拉长到 15.6 ms。
起因 帧率限制、数据包发送用 Sleep(短暂等待)方式实现 → 结果 操作系统只以 15.6 ms 为单位唤醒线程 → 画面表现 帧间隔和输入发送间隔忽长忽短
- 症状
- 一卡一卡
- 因素
- 抖动
- 谁会遇到
- 只有我
- 何时出现
- 一直
- 负责方
- 主责 研发团队·客户端开发
- 研发团队要做的事
- 使用高精度定时器,用基于事件、垂直同步的节奏控制(pacing)代替等待。
- 数值参考
- 以 15.6 ms 为单位无法对齐 16.7 ms 的间隔,帧间隔会在 15.6 ms 和 31.2 ms 之间来回跳。
- 监控图上
- 一直偏高 · 帧间隔分布
- 查看位置
- 查看 PresentMon 的 MsBetweenPresents(帧间隔)分布,以及 powercfg /energy 报告中的“Platform Timer Resolution”项(修改过定时器精度的进程)
- 确认依据
- 帧间隔集中在 15.6 ms、31.2 ms 这类 15.6 ms 的整数倍上,游戏也没有请求更高的定时器精度
- 排除依据
- 间隔分布均匀,和定时器关系不大,看“后台进程占用 CPU”或帧负载
- 确认手段
- 需在玩家侧环境确认
- 深入了解
- 早期的 Windows 中,只要有一个程序把定时器改成 1 ms,就会对所有程序生效。所以曾有“开着浏览器游戏会更流畅”的说法。从 Windows 10 2004 版起只对发出请求的程序生效;Windows 11 对最小化、完全被遮挡且不发声的窗口,可能不采纳其请求。
出处
- _WDF_TIMER_CONFIG (wdftimer.h) Microsoft
普通定时器的精度为系统时钟 tick 间隔,默认 15.6 ms;高精度定时器为 1 ms - timeBeginPeriod function (timeapi.h) Microsoft
Windows 10 2004 之前是全局设置,之后只对发出请求的进程生效;Windows 11 不保证被遮挡或最小化窗口的进程获得高精度 - CreateWaitableTimerExW function (synchapi.h) Microsoft
高精度可等待定时器标志 CREATE_WAITABLE_TIMER_HIGH_RESOLUTION - PresentMon Capture Application (README-CaptureApplication.md) Intel
MsBetweenPresents:本次 Present() 调用与上一次调用之间的时间(ms) - Results for the Idle Energy Efficiency Assessment Microsoft
默认系统定时器精度 15.6 ms,在能耗报告的“Platform Timer Resolution”项中查找修改过定时器精度的进程 - Powercfg command-line options Microsoft
powercfg /energy:分析系统并生成能耗报告(HTML)
相关原因
同一层:L2 客户端操作系统与设备
其他层中同样导致“一卡一卡”的原因
查看含图示和实验的原卡片