异步与并发:把工作搬离主线程
当单线程已经装不下所有逻辑,答案是把可以延迟 / 并行的工作搬走。
可以异步的三类工作
| 类型 | 例子 | 手段 |
|---|---|---|
| 加载 | 关卡资产、大纹理 | 异步加载(流式加载 / LoadPackageAsync) |
| 计算 | 路径规划、大量数学 | Task Graph 工作线程 |
| IO | 存档、日志、网络 | 异步 IO 接口 |
加载的纪律
- 启动与关卡切换的花销属于设计问题:用 Loading Screen + 异步加载,不要在玩家操作时同步 LoadObject(一次同步加载就是一次尖峰);
- 用软引用(TSoftObjectPtr)持有资产,需要时再异步加载;
- 关卡层面用 World Partition / Level Streaming 按区域加载。
详见官方的资产异步加载与"加载与卸载关卡"相关章节。同步加载是帧时间尖峰最常见的来源,没有之一。
并发的纪律
- 不要在主线程里 Sleep / 长循环——用定时器或异步 Task;
- 用 Task Graph / Async Task 时,注意跨线程访问 UObject 的限制(游戏线程的对象不能在工作线程安全读写)——先复制数据再投递;
- 并行后用
stat threads/ Insights 检查实际并行度:如果所有任务都在等一个锁,并行就是假的。
并发不是银弹
如果游戏线程本来就闲(Frame 时间低),并发化反而增加复杂度与同步开销。只有当 Insights 显示主线程在排队等任务时,并行化才有明确收益。
