游戏卡顿白皮书 › L1 客户端游戏进程
垂直同步(V-Sync)与渲染队列 V-Sync, render queue
原因 ID cg-vsync · 主责 研发团队·客户端开发 · 配合 外部·外部
在含图示和实验的完整版中打开此卡片 →
GPU 画好的帧先在队列里攒几张,再按显示器刷新周期送出,这段时间里输入响应就会变迟。
起因 显卡驱动预先在队列里攒 1~3 帧 → 结果 输入体现到画面上要多花这么久 → 画面表现 ping 不高,操作却发沉、迟钝
- 症状
- 操作延迟, 一卡一卡
- 因素
- 延迟
- 谁会遇到
- 只有我
- 何时出现
- 一直
- 负责方
- 主责 研发团队·客户端开发 · 配合 外部·外部
- 研发团队要做的事
- 支持低延迟模式,缩短帧队列,提供略低于刷新率的帧率上限选项,手机上开启帧节奏控制(frame pacing)功能。
- 外部要做的事
- 引导玩家配合可变刷新率显示器设置略低于刷新率的帧率上限,并开启显卡驱动的低延迟模式。
- 数值参考
- 60 Hz 下每帧 16.7 ms。CPU 比 GPU 或屏幕刷新周期快、三帧队列(DirectX 11 默认值)被塞满时,会多出 50 ms。双缓冲垂直同步下,耗时 17 ms 的帧要等到下一次屏幕刷新时刻(33.3 ms),这期间上一帧会多显示一次。
- 监控图上
- 一直偏高 · 输入到画面的延迟
- 查看位置
- 切换垂直同步、低延迟模式、帧率上限,对比 PresentMon 的 MsClickToPhotonLatency、MsAllInputToPhotonLatency(从鼠标、键盘输入到送往屏幕)和 DisplayLatency。MsPCLatency(PC 收到输入后到送往屏幕)只在游戏发出 PC Latency 事件时才会记录
- 确认依据
- 开启垂直同步或不设帧率上限时,这段延迟增加一两帧(几十 ms),在低延迟模式或略低于刷新率的帧率上限下减少。ping 不变
- 排除依据
- PC 内部延迟很低、操作仍然迟,看“显示器/输入设备/帧生成延迟”;ping 高则是网络侧
- 确认手段
- 需在玩家侧环境确认
- 深入了解
- 垂直同步(V-Sync)是只在显示器刷新画面的那一刻才送出新帧的设置。画面撕裂会消失,但等待这一刻会让输入响应变迟;FPS 低于 60 时,还会在 60 和 30 之间来回切换,出现一卡一卡。可变刷新率显示器会配合帧准备好的时间刷新画面,减少这段等待。手机上也会出现同样的情况。30 FPS 的游戏如果不能把帧均匀地对齐到 60 Hz 屏幕上送出,平均虽是 30 FPS,每帧停留的时间却像 49、16、33 ms 这样忽长忽短,出现一卡一卡(Android 开发文档中的例子)。可以用 Android 的帧节奏控制(frame pacing,让帧输出间隔均匀)库或引擎的同类选项来缓解。
出处
- IDXGIDevice1::SetMaximumFrameLatency Microsoft
驱动可在队列中积攒的帧数默认为 3(1~16) - Reduce latency with DXGI 1.3 swap chains Microsoft
Present 会一直阻塞到队列空出,画完到显示几乎要多等一帧;用可等待交换链(waitable swap chain)缓解 - Frame Pacing library Android (Google)
60 Hz 屏幕上没有新帧时会重复显示上一帧;举例说明 30 FPS 游戏的帧耗时变成 49、16、33 ms 这样忽长忽短 - PresentMon Capture Application (README-CaptureApplication.md) Intel
MsPCLatency(PC 收到输入到送往屏幕)、MsClickToPhotonLatency(鼠标点击到画面)、MsAllInputToPhotonLatency(键盘、鼠标输入到画面)、DisplayLatency(帧提交到送往显示器) - PresentMon Console Application (README-ConsoleApplication.md) Intel
MsPCLatency 需要应用发出 PC Latency 事件才会记录(--track_pc_latency),MsAllInputToPhotonLatency 以键盘、鼠标输入为准
相关原因
同一层:L1 客户端游戏进程
其他层中同样导致“操作延迟”的原因
查看含图示和实验的原卡片