# Profiler Workflow ## 先说结论 `XCEngine::Debug::Profiler` 当前不是成熟的分析器,而是一个“轻量级 CPU 埋点接口壳”。它已经能表示 profile 区段,但还没有形成完整的数据消费闭环。 这不是坏事,但文档和使用方式必须诚实: - 它适合做早期埋点。 - 它不适合被描述成 Unity Profiler 那种完整时间线工具。 ## 现在真正能做什么 当前实现中,`BeginProfile` / `EndProfile` 会记录: - 区段名 - 开始时间 - 结束时间 - 线程哈希 这证明设计方向是对的:接口已经在向“作用域埋点”靠拢。 但是同一时间,以下能力还没打通: - 没有公开的样本读取 API。 - `MarkEvent`、`SetMarker`、`ExportChromeTracing` 仍是空实现。 - `EndFrame` 会直接清空样本。 所以当前更合理的定位是: - 先把埋点位置和调用习惯稳定下来; - 再逐步补数据导出、可视化和多线程时间线。 ## 为什么先做成单例 对调试工具而言,单例有一个现实优势:调用点成本极低。 ```cpp XE_PROFILE_FUNCTION(); ``` 这种接法非常适合逐步给引擎关键路径加埋点,而不需要把 profiler 对象层层传递。 代价也很明显: - 当前实现只有一个全局栈。 - 如果多个线程同时写入,栈结构和样本语义都会混乱。 这就是为什么文档必须明确写“当前只适合受控单线程埋点”。 ## 推荐工作流 当前阶段推荐把 `Profiler` 用在下面这些场景: 1. 主线程 CPU 热路径粗测。 2. 某个函数或阶段的进入/退出埋点。 3. 为未来时间线导出预留稳定的区段命名。 推荐写法: ```cpp using namespace XCEngine::Debug; Profiler::Get().Initialize(); Profiler::Get().BeginFrame(); XE_PROFILE_BEGIN("SceneUpdate"); // ... XE_PROFILE_END(); Profiler::Get().EndFrame(); ``` ## 和 Unity Profiler 的差异 可以把它理解为“还在早期形态的引擎内 CPU 埋点接口”,而不是 Unity Profiler 的直接对标物。 Unity Profiler 已经提供: - 完整的帧时间线 - 多线程可视化 - 统计聚合 - UI 分析工具 XCEngine 当前的 `Profiler` 还没有这些能力。它更像是先把“埋点 API”立住,再逐步扩展后端。 ## 当前使用时最该注意的事 - `BeginProfile` / `EndProfile` 必须按栈顺序配对。 - 不要跨线程共享同一条 profile 栈。 - 不要指望 `ExportChromeTracing` 现在就会产出文件。 - 如果你在 `EndFrame` 之后再找样本,当前实现里它们已经被清掉了。 ## 下一阶段最值得补的能力 如果继续把这个模块做实,最有价值的方向通常是: 1. 暴露只读样本访问接口。 2. 把样本按线程分桶。 3. 实现 Chrome Trace / Perfetto 导出。 4. 在编辑器里增加最小时间线浏览能力。 ## 相关 API - [Debug](../../XCEngine/Debug/Debug.md) - [Profiler](../../XCEngine/Debug/Profiler/Profiler.md) - [BeginProfile](../../XCEngine/Debug/Profiler/BeginProfile.md) - [EndProfile](../../XCEngine/Debug/Profiler/EndProfile.md) - [ExportChromeTracing](../../XCEngine/Debug/Profiler/ExportChromeTracing.md)