外观
路线 A|Cocos 引擎、渲染与性能
A3|Advanced Performance:CPU、GPU、内存与帧稳定性
适用基础: A1、A2、Stage05、Stage07 目标: 建立可复现、可量化、可回归的系统性能分析能力。
一、从“卡”改成指标
text
FPS:频率
Frame Time:单帧耗时
CPU/GPU:主导瓶颈
Memory:常驻、峰值、碎片和泄漏
IO:加载、解码、上传和写盘60 FPS 的预算约 16.67 ms,不能把 CPU、GPU、脚本和余量都各自花满。帧稳定性还要看 P95/P99 和长帧,而不只是平均值。
二、证据链
text
现象 → 固定场景 → 记录基线 → 定位维度 → 最小修改
→ 重测同一指标 → 真实设备回归 → 保留报告性能分析的第一步不是优化,而是建立可比较的基线:同一版本、设备、分辨率、场景、操作和缓存条件下,分别记录平均值、P95/P99、长帧、峰值内存和稳定值。冷启动、热启动、战斗峰值和场景切换属于不同工作负载,不能混成一条 FPS 曲线。
三、CPU Cache 与数据组织
连续数组、SoA、减少指针跳转和避免热路径临时对象通常比“换一个容器名字”更重要。使用 Native profiler 和采样火焰图确认热点,不能凭代码长度判断耗时。
Cache line 会把相邻字节一起带入缓存,因此顺序遍历通常比随机指针追踪更友好。AoS 便于处理完整对象,SoA 便于只扫描少量热字段;真正选择取决于每帧访问模式。Branch Prediction 依赖分支规律,杂乱对象类型和不可预测状态会让流水线频繁清空,但只有在采样热点中出现时才值得改写数据布局。
四、内存分配与碎片
高频 new/delete 会增加 allocator、锁、碎片和 GC/JSB 交互成本。对象池只有在生命周期和复位协议清晰时才有价值;池过大、复位遗漏和长期持有也会制造内存问题。
对象池的收益来自减少分配和初始化,但代价是池内对象常驻、复位逻辑复杂、事件/Timer 残留和峰值容量。判断是否值得使用,要同时比较分配次数、GC、CPU、内存峰值、稳定值和复位错误;不能因为“创建次数下降”就判定优化成功。
通用 allocator 服务不同大小和生命周期的对象,容易产生元数据、锁和碎片成本。Arena 把同一阶段对象集中分配并整体释放,Memory Pool 固定或分级管理可复用块;它们通过限制生命周期模型换取效率。若对象释放顺序不可控、跨线程或必须单独析构,专用分配器的复杂度会明显上升。
五、CPU/GPU 同步
读回 GPU、等待纹理上传、强制 flush 或提交后立即查询结果,都可能把异步流水线变成同步等待。Frame pacing 还受平台刷新率、VSync 和后台策略影响。
CPU 和 GPU 通常流水工作:CPU 准备后续帧时 GPU 仍执行之前命令。同步读回、资源覆写或缓冲不足会迫使一方等待另一方。平均 60 FPS 仍可能因帧间隔不均匀产生卡顿,因此 Frame Pacing 要看 present 间隔、队列深度和长帧分布,而不只是总吞吐。
六、多线程与 Job System
后台适合纯数据、解码和批处理,不能直接改 Node/Renderer/脚本。锁竞争、false sharing、任务过细和主线程合并成本会抵消收益。先定义所有权和完成点,再设计线程。
False Sharing 指不同线程写入同一 cache line 内的不同字段,虽然没有逻辑共享,缓存一致性仍会让整行反复迁移。Job System 通常把任务分解、依赖计数和 worker 队列结合起来;任务只有在输入不可变、输出 owner 清楚并且粒度足够时才能扩展。主线程最终合并结果仍属于帧预算。
七、启动与加载
把首屏拆成启动、脚本初始化、场景反序列化、纹理解码、上传、首帧渲染。分阶段加载不是把所有工作搬到后台,而是控制关键路径和峰值。
八、Native Crash 与性能回归
任何优化都要同时记录正确性、内存、CPU、GPU、设备和版本。Native crash 必须保留符号化堆栈、构建 commit、设备信息和复现步骤;“更快但偶发崩溃”不是优化。
九、性能问题的知识化拆解
把一个性能问题拆成四个问题:
text
哪一个资源超预算?
它属于 CPU、GPU、Memory 还是 IO?
哪个调用或数据结构制造了成本?
修改后成本是否转移到别的维度?CPU 热点看采样栈和调用次数,GPU 热点看分辨率/overdraw/Shader 对照,内存问题看对象引用和分配轨迹,IO 问题看等待时间和峰值。四类证据不能互相替代。
十、常见错误方案
text
只看平均 FPS:忽略长帧
先优化最显眼代码:没有热点证据
只在编辑器测:设备和构建模式不同
对象池越大越好:常驻内存和复位成本上升
DrawCall 越低越好:可能换来更高 overdraw 或 Shader 成本十一、练习与答案
1. CPU 只有 8 ms,为什么仍然掉帧?
GPU、提交同步、VSync、平台调度或长帧分布可能超过预算;必须同时看 GPU 和 frame pacing。
2. 如何判断对象池是否有效?
比较同一场景下分配次数、GC、CPU、内存峰值、稳定值和复位错误;只看创建次数减少不够。
3. 优化报告最少包含什么?
版本、设备、场景、操作、基线、修改、指标、统计方法、正确性和回滚条件。
十二、阶段输出
完成 A3 后应能提交一份可复现性能报告,并把指标接入回归检查,而不是只给出“优化后感觉更流畅”。
