| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 |
VectorAdd 内存访问优化案例
概述
本样例演示如何使用 msOpProf 工具定位 UB-GM 之间数据搬运效率低的性能瓶颈,并通过增大 TILE_LENGTH(单次搬运粒度)来减少搬运次数、提升带宽利用率。
适用场景
- 算子端到端耗时高,
TILE_LENGTH远小于 UB 单次可容纳的最大元素数。 - UB-GM 之间搬运次数过多、单次搬运量过小,带宽利用率低。
支持的产品范围
- 昇腾950PR&950DT系列产品
- 昇腾A3系列产品
- 昇腾A2系列产品
目录结构
├── sample_memory_access/
│ ├── CMakeLists.txt // 编译工程文件
│ ├── memory_access.asc // Ascend C 算子实现(优化前版本)
│ ├── optimize.diff // 优化前->优化后的 patch 文件
│ └── README.md // 本说明文件
样例描述
核心逻辑
本样例实现向量加法算子 y[i] = x[i] + bias[i],数据规模为 80M 个 half 元素(160 MB),8 核并行处理。算子内部按 TILE_LENGTH 粒度循环执行 DataCopy→Add→DataCopy。
每个核分配 3 个 UB buffer(inQueueX、inQueueBias、outQueueY),每个 buffer 大小为 TILE_LENGTH * sizeof(half) 字节,总 UB 占用 = 3 * TILE_LENGTH * 2 字节。
说明:本案例重在性能优化演示,不包含标杆数据生成和精度校验步骤,数据规模可以核间均分,不涉及尾核处理。示例代码省略了 ACL Runtime API(如 aclInit、aclrtMalloc、aclrtSynchronizeStream)的返回值检查,生产环境应补充错误处理与资源释放。
优化改动
优化前 TILE_LENGTH = 2048,每次搬运仅 4KB,每核需循环 5120 次 TILE;优化后 TILE_LENGTH = 20480,每次搬运 40KB,每核仅需循环 512 次 tile,单次搬运量大幅增加,减少搬运次数。
完整改动见 optimize.diff,仅修改一行常量定义:
-constexpr uint32_t TILE_LENGTH = 2048;
+constexpr uint32_t TILE_LENGTH = 20480;
编译运行
环境准备
请参照官方文档完成开发环境配置:算子工具开发环境安装指导。
编译算子
在 sample_memory_access/ 目录下执行:
mkdir -p build && cd build
cmake .. -DCMAKE_ASC_ARCHITECTURES=dav-2201
make -j4
cd ..
编译完成后,build 目录下生成 demo 可执行文件。
- 编译选项说明
| 选项 | 可选值 | 说明 |
|---|---|---|
CMAKE_ASC_ARCHITECTURES |
dav-2201、dav-3510 |
NPU 架构:dav-2201 对应昇腾A2系列产品/昇腾A3系列产品,dav-3510 对应昇腾950PR&950DT系列产品 |
注意:切换架构前需清理 cmake 缓存,可在 build 目录下执行
rm CMakeCache.txt后重新 cmake。
算子运行与性能采集
优化前:采集基线数据
msopprof ./build/demo 0
命令执行后在当前目录生成 OPPROF_{timestamp}_XXX/ 文件夹,包含以下 CSV 文件:
OPPROF_{timestamp}_XXX/
├── OpBasicInfo.csv // 算子基本信息(名称、核数、总耗时、频率)
├── PipeUtilization.csv // 各流水线单元耗时和占比
├── ArithmeticUtilization.csv // Cube/Vector 指令 cycle 占比和计算量
├── Memory.csv // 内存读写带宽和数据搬运量
├── MemoryL0.csv // L0A/L0B/L0C 读写带宽
├── MemoryUB.csv // UB 读写带宽(Vector/Scalar)
├── L2Cache.csv // L2 Cache 命中率
├── ResourceConflictRatio.csv // Bank conflict 和资源冲突占比
└── visualize_data.bin // MindStudio Insight 可视化文件
优化前:分析性能瓶颈
重点查看以下 CSV 文件中的关键字段:
| 文件 | 关键字段 | 说明 |
|---|---|---|
OpBasicInfo.csv |
Task Duration(us) |
记录端到端耗时作为基线 |
OpBasicInfo.csv |
Block Dim |
确认多核已启用 |
OpBasicInfo.csv |
Current Freq / Rated Freq |
排除降频干扰 |
PipeUtilization.csv |
aiv_time(us) |
单核 AIV 执行时间 |
PipeUtilization.csv |
aiv_mte2_ratio |
MTE2(GM→UB)占比 |
PipeUtilization.csv |
aiv_mte3_ratio |
MTE3(UB→GM)占比 |
PipeUtilization.csv |
aiv_vec_ratio |
Vector 指令 cycle 占比 |
Memory.csv |
aiv_mte2_instructions |
MTE2 指令条数 |
Memory.csv |
aiv_mte3_instructions |
MTE3 指令条数 |
Memory.csv |
GM_to_UB_datas(KB) |
GM→UB 总搬运量 |
Memory.csv |
UB_to_GM_datas(KB) |
UB→GM 总搬运量 |
Memory.csv |
GM_to_UB_bw_usage_rate(%) |
GM→UB 带宽利用率 |
Memory.csv |
UB_to_GM_bw_usage_rate(%) |
UB→GM 带宽利用率 |
Memory.csv |
aiv_gm_to_ub_bw(GB/s) |
GM→UB 实际带宽 |
Memory.csv |
aiv_ub_to_gm_bw(GB/s) |
UB→GM 实际带宽 |
实测优化前关键指标:
| 指标 | 优化前实测值 | 说明 |
|---|---|---|
Task Duration(us) |
2049.78 | 端到端耗时高 |
Block Dim |
8 | 8核并行 |
Current Freq / Rated Freq |
1650 / 1650 | 满频运行,无降频 |
aiv_time(us)(单核) |
2006.67 ~ 2049.09 | 各核执行时间 |
aiv_mte2_ratio |
86.04% ~ 86.33% | MTE2(GM→UB)占比高,每次仅搬运 4KB |
aiv_mte3_ratio |
38.87% ~ 40.75% | MTE3(UB→GM)占比 |
aiv_vec_ratio |
10.15% ~ 10.36% | Vector 计算占比低 |
aiv_mte2_instructions(单核) |
10241 | MTE2 指令条数多 |
aiv_mte3_instructions(单核) |
5121 | MTE3 指令条数多 |
GM_to_UB_datas(KB) |
40960.00 | GM→UB 总搬运量(单核) |
UB_to_GM_datas(KB) |
20480.00 | UB→GM 总搬运量(单核) |
GM_to_UB_bw_usage_rate(%) |
8.66% ~ 8.85% | GM→UB 带宽利用率低 |
UB_to_GM_bw_usage_rate(%) |
5.10% ~ 5.21% | UB→GM 带宽利用率低 |
aiv_gm_to_ub_bw(GB/s) |
19.06 ~ 19.47 | GM→UB 实际带宽低 |
aiv_ub_to_gm_bw(GB/s) |
9.53 ~ 9.73 | UB→GM 实际带宽低 |
分析结论:TILE_LENGTH = 2048 导致每核需执行 5120 次 tile 循环(MTE2 指令 10241 条/核),每次 DataCopy 仅搬运 4KB 数据,实际有效带宽利用率低(GM→UB 仅 8.66%~8.85%,UB→GM 仅 5.10%~5.21%)。
应用优化并重新采集
# 应用优化 patch
patch -p1 < optimize.diff
# 重新编译(同一 build 目录)
cd build && make -j4 && cd ..
# 采集优化后数据
msopprof ./build/demo 0
优化后:对比验证
实测优化后关键指标:
| 指标 | 优化前 | 优化后 | 对比结论 |
|---|---|---|---|
Task Duration(us) |
2049.78 | 892.02 | 2.30x 加速 |
Block Dim |
8 | 8 | 核数不变 |
Current Freq / Rated Freq |
1650 / 1650 | 1650 / 1650 | 满频运行,无降频 |
aiv_time(us)(单核) |
2006.67 ~ 2049.09 | 771.19 ~ 891.39 | 单核时间降至约 40% |
aiv_mte2_ratio |
86.04% ~ 86.33% | 84.70% ~ 86.76% | MTE2 占比基本不变 |
aiv_mte3_ratio |
38.87% ~ 40.75% | 24.92% ~ 29.29% | MTE3 占比下降,大粒度搬运效率提升 |
aiv_vec_ratio |
10.15% ~ 10.36% | 12.33% ~ 14.10% | Vector 占比提升 |
aiv_mte2_instructions(单核) |
10241 | 1025 | GM→UB 指令次数减少约 10x |
aiv_mte3_instructions(单核) |
5121 | 513 | UB→GM 指令次数减少约 10x |
GM_to_UB_datas(KB) |
40960.00 | 40960.00 | 总搬运量不变 |
UB_to_GM_datas(KB) |
20480.00 | 20480.00 | 总搬运量不变 |
GM_to_UB_bw_usage_rate(%) |
8.66% ~ 8.85% | 19.91% ~ 23.02% | GM→UB 带宽利用率提升约 2.3x |
UB_to_GM_bw_usage_rate(%) |
5.10% ~ 5.21% | 11.73% ~ 13.56% | UB→GM 带宽利用率提升约 2.3x |
aiv_gm_to_ub_bw(GB/s) |
19.06 ~ 19.47 | 43.82 ~ 50.65 | GM→UB 实际带宽提升约 2.3x |
aiv_ub_to_gm_bw(GB/s) |
9.53 ~ 9.73 | 21.91 ~ 25.33 | UB→GM 实际带宽提升约 2.3x |
恢复源码
patch -R -p1 < optimize.diff
性能调优总结
| 优化前现象 | 调优动作 | 原因 |
|---|---|---|
| UB-GM 搬运次数多、单次搬运量小、带宽利用率低 | 将 TILE_LENGTH 从 2048 增大至 20480(满足 UB 容量约束) |
大粒度搬运减少 DataCopy 调用次数,摊薄启动开销,提升有效带宽利用率 |
注意事项
- 上板功能需要真实 NPU 环境,编译出的二进制应在目标设备上运行。
- 本案例环境为 Ascend 910B4 + CANN 9.1.0-beta.3,数据因环境不同可能会有差异,属于正常现象。