性能窗口:平均 FPS 会掩盖连续超预算
自动关联目录:性能窗口:平均 FPS 会掩盖连续超预算
核心判断:平均 FPS 回答“总吞吐怎么样”,不能回答“玩家是否连续卡住”。加载、流式和大规模玩法必须同时记录分位数、连续超预算、队列等待和阶段归因。
一、业务冲突:平均值变好,体验仍可能更差
流式进入区域时会同时发生对象决策、资源完成、Actor Spawn、Component 注册和 GPU 资源提交。若少数帧非常慢,其余帧很快,平均 FPS 仍可能合格;但玩家在移动或战斗关键时刻感受到的是连续慢帧和输入延迟。
同样,内存只看当前值会漏掉持续增长,只看峰值又无法判断回收是否成功。性能系统必须表达“值、趋势、持续时间和当时发生了什么”。
二、实际实现:观测面已经超过平均 FPS
实践中的流式快照同时记录平均帧率、当前与峰值帧时间、连续超预算次数、流式活跃时的帧率变化、评估耗时、物理内存趋势、恢复延迟、唯一资源估算、流入/流出速率、单帧流入字节峰值、预加载成功率与 P95、首个可玩时间、LOD 代理、Draw Call 和 GPU 时间。
拓扑重建还记录原因、全量/增量/回退类型、Dirty Root、资源查询命中、各阶段耗时和失败原因。这个方向正确:同一帧的结果和原因终于可以关联。
三、值得保留:把控制信号和结果信号分开
- 内存压力、有效流出模式和重复加载保护是控制状态;内存、重载率和恢复延迟是结果。
- 流入对象数与流入字节分开,避免把许多小对象等同于一个大资产。
- 连续超预算比单帧最大值更接近卡顿体感。
- 拓扑重建原因与耗时同帧记录,可以区分正常增量和全量回退。
- 固定容量窗口限制诊断本身的内存成本。
四、结构性缺陷:没有工作量和阶段标签,跨样本比较会失真
一个 P95 数值只有在工作负载一致时才可比较。候选对象数、观察点数、流入字节、设备、构建配置和运行阶段不同,数值变化不一定是代码回归。固定帧数窗口在高低帧率下覆盖的实际秒数不同,也会改变统计含义。
进程内存趋势还会受到其他系统干扰;流式活跃与 FPS 下降只能说明相关,不能证明因果。若没有 Trace 区间或实验标签,就容易把 GC、Shader 创建或网络突发归因给同一时段的流式。
五、目标设计:以 Workload × Phase × Window 组织证据
每个性能样本携带运行目标、设备档位、构建配置、场景规模、活跃对象、工作字节、阶段和会话 ID。窗口按真实时间切分,另保留事件窗口捕获流入洪峰、GC 和全量重建前后。
SampleKey = Session + Target + DeviceTier + Build + Workload + Phase
FrameCost = GameThread + RenderThread + GPU
CauseTags = StreamIn | Materialize | GC | Rebuild | NetworkBurst主要判据同时包含:
再用 P50/P95/P99/Max 描述分布,用“每千候选评估耗时”“每 MiB 流入主线程提交耗时”等归一化指标解释伸缩性。绝对帧预算仍保留,因为玩家体验最终不按对象数归一化。
六、回归门禁:性能与正确性必须同批验收
门禁应覆盖冷启动、热缓存、快速穿越、往返边界、多观察点、内存压力、全量重建和长会话。每个用例既检查性能,也检查可见空洞、错误流出、权威碰撞、重复事件和旧回调写入。
合成示例:两次运行平均都是 16 ms,A 的 P99 为 18 ms,B 每隔一段时间出现连续三帧 45 ms;平均值相同,B 的交互体验明显更差。数字只用于说明指标,不代表历史结果。
最终决策规则:任何性能结论都必须说明工作量、阶段、窗口和目标;平均值用于看吞吐,长尾与连续超预算用于看体验。