基于PMU构建一个AI推理性能分析工具
通常,AI推理性能的分析集中在模型层面,例如操作符融合、量化、内核选择和运行时行为。但当我开始在Arm Cortex-A CPU上对Transformer工作负载进行性能分析时,我不断发现一个奇怪的现象:问题并不出在模型本身,而是在CPU上。
这让我深入探索了微架构层面的行为:流水线停顿、缓存驻留情况、TLB频繁切换、分支预测器不稳定以及内存分配器开销等问题。这些信号对推理性能的影响与模型结构相当,有时甚至更为显著。
我开发了InferPerf,旨在从CPU侧的角度深入分析这一问题,并让工程师、学生及使用Arm设备的爱好者能够清晰看到这些细节。我的目标仅仅是揭示推理为何变慢,而不仅仅是指出耗时的位置。
本项目存在的原因
大多数性能分析工具仅停留在操作符级别的指标,它们告诉你哪个层次较慢,却无法解释“为什么”。而在Arm Cortex-A CPU上,“为什么”往往隐藏在微架构深处:
•ILP(指令级并行)限制
•L1/L2缓存驻留行为
•TLB(翻译查找表)频繁切换
•分支预测器稳定性
•内存分配器开销
这些信号在不使用CPU内部的硬件性能监控单元(PMU)时是不可见的。InferPerf可使这些信号变得可见。
InferPerf的功能
InferPerf 是一款基于PMU的Arm Cortex-A CPU性能分析工具。它通过perf收集的硬件计数器,捕获推理过程中CPU的底层执行行为。随后对这些信号进行分析,生成火焰图,识别瓶颈,并提供针对性的优化建议。
该工具设计为可复现、确定性、支持微架构,并且易于在树莓派上运行。
架构
InferPerf 基于一个可复现的性能分析流水线构建:
1. 推理套件
一个确定性工作负载运行器,可稳定预热过程,控制变异性,并确保执行结果的可重现性。
2. PMU采样层
使用perf工具从Arm PMU收集硬件计数器数据,包括周期数、指令数、缓存未命中、TLB未命中、分支预测错误以及空闲周期。
3. 火焰图生成器
将性能分析堆栈转为火焰图,用于可视化热点路径、内存分配开销以及运行时行为。
4. 瓶颈分类器
一种针对 Arm Cortex-A 执行特性进行优化的基于规则的分类器。它可识别 ILP 限制、驻留问题、TLB 切换、分支不稳定性以及内存分配器压力。
5. 基准比较系统
通过比较IPC、缓存行为、TLB行为、分支行为和空闲周期,验证性能提升情况。
构建说明
InferPerf适用于Arm Cortex-A CPU,但完整流水线是针对Raspberry Pi 4B专门构建和测试的。其他设备可能需要调整PMU事件设置或perf配置。
1. 安装依赖项
2. 克隆 InferPerf 并设置环境
InferPerf 包含以下内容:
- 确定性工作负载(workloads/)
- ONNX 模型(models/)
- MobileNetV2 示例
- Transformer 编码器基线模型 + 优化版本
3. 运行基准分析
InferPerf 的主要工作流程为:分析 → 验证 → 对比
生成基准配置文件:
该命令会执行以下操作:
- 运行工作负载
- 收集 PMU 计数器
- 生成火焰图
- 分类瓶颈
- 存储可重复的基准数据
要确认您的设置正确,应看到如下所示的输出:
4. 验证基准线
在分析工作负载后,验证可重复性:
该功能将新鲜的PMU数据与缓存的基准线进行比较,并报告差异值。对于功能测试而言,这实际上相当于重新分析完全相同的脚本,因此你应该会看到非常相似的数值(左右浮动一些噪声)。
5. 比较两个工作负载
InferPerf 可以将两个工作负载并排进行比较:
代码
这会生成 PMU 指标、瓶颈分类、火焰图、优化建议,以及按令牌和每次运行的对比结果。
你应该看到类似以下的输出:
6. 可选:使用交互模式
运行:
或
无参数时会打开一个引导式选择菜单,如下所示:
结果
InferPerf 使用 Cortex-A72 处理了一个演示用的 Transformer-Encoder 工作负载,该工作负载可在 InferPerf 仓库中获取。
IPC 改进:IPC 提升 +20.53
微架构改进:缓存未命中减少、TLB 未命中减少、分支预测错误减少以及空闲周期减少
本文编译自hackster.io





