三条线程:分工与瓶颈定位
UE 的帧由几条线程协作完成。找瓶颈的第一步就是知道"现在哪条线满了"。
三条核心线程
| 线程 | 职责 | 慢了的表现 | 排查工具 |
|---|---|---|---|
| 游戏线程(Game) | Tick、蓝图逻辑、物理、AI | 一切逻辑卡:敌人不动、UI 延迟 | stat game / Insights |
| 渲染线程(Draw / Render) | 可见性剔除、DrawCall 提交 | 逻辑顺但画面卡 | stat render / Insights |
| GPU | 着色器执行、像素填充 | 渲染线程等 GPU | stat gpu / GPU Visualizer |
一个经典的误判
"游戏卡" → 大家都觉得是显卡不行 → 换了 4090 还是卡 → 一看 stat unit:游戏线程 20ms,GPU 5ms。瓶颈在 CPU 逻辑,显卡在摸鱼。三条线程的性能是相互依存的——只有最慢的那条决定帧率。
怎么读帧时间
stat unit 的输出长这样(示意):
Frame: 20.5ms
Game: 18.2ms ← 游戏线程
Draw: 8.1ms ← 渲染线程
GPU: 6.4ms ← GPU
规则:
- Game 时间 ≈ Frame 时间 → 游戏线程瓶颈;
- Draw 时间 ≈ Frame 时间 → 渲染线程瓶颈;
- GPU 时间 ≈ Frame 时间(且 Draw < GPU)→ GPU 瓶颈;
- Frame 明显大于各项 → 等待 / 同步开销(如垂直同步、平台限制)。
注意并行性:渲染线程通常与游戏线程并行跑(游戏线程在算第 N+1 帧时渲染线程在画第 N 帧)。所以 Frame 时间不是简单相加,瓶颈判断看"谁达到了上限"。
多核与 Task Graph
游戏线程不是孤军奋战:UE 用 Task Graph 把很多工作分散到工作线程(物理、动画、粒子、加载……)。stat threads 可以看各工作线程的负载。"游戏线程瓶颈"有时其实是一个被占满的工作线程连带拖住了主线程——Insights 的 Tracks 视图能看出这种依赖。
