110 lines
3.1 KiB
Markdown
110 lines
3.1 KiB
Markdown
|
|
# 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)
|