L2 Cache Mode 最佳实践样例【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit概述MTE2将数据从Global MemoryGM搬运到Unified BufferUB时可通过asc_copy_gm2ub_align接口的l2_cache_mode参数本样例使用基于指针的C语言编程显式配置数据在L2 Cache中的管理策略。本样例说明复用数据和流式数据两大类场景下如何选择合适的L2 Cache模式来优化MTE2搬运性能以及在启用L2 Cache的前提下如何通过分片策略提升L2 Cache命中率。复用数据场景数据需多次读取Case1: 整块重复搬4次l2_cache_mode0NORMAL → 整块数据远超L2容量命中率极低展示未分片时的性能瓶颈。 Case2: N方向切4份每份连续搬4次l2_cache_mode0NORMAL → 分片后单份工作集降至L2容量以内命中率提升。流式数据场景数据只读一次Case3: Add 双缓冲l2_cache_mode0NORMAL基准。 Case4: 同Case3但将l2_cache_mode设为4DISABLE跳过L2 Cache → 与Case3对比。本样例支持的产品及CANN软件版本产品CANN软件版本Ascend 950PR/Ascend 950DT CANN 9.1.0目录结构介绍├── set_l2_cache_mode │ ├── scripts │ │ └── gen_data.py // 输入数据和真值数据生成脚本文件 │ ├── CMakeLists.txt // 编译工程文件 │ ├── set_l2_cache_mode.asc // 样例入口kernel 调用 main 函数 │ ├── set_l2_cache_mode.h // Kernel 实现DataCopyRepeat Add │ ├── data_utils.h // 数据读入写出函数 │ ├── README.md // 样例说明文档 │ └── README_en.md // 样例说明文档英文样例描述C-API的GM→UB搬运接口通过入参l2_cache_mode来控制本次搬运数据在L2 Cache中的管理策略取值及含义详见asc_copy_gm2ub_align接口说明。围绕上述两类场景本样例设计了4个Case进行对比验证数据复用场景Case1-2 本组场景输入为half类型二维矩阵shape为[12288, 12288]。使用asc_copy_gm2ub_align将数据从GM搬运到UB通过对比不同搬运策略下的L2 Cache命中率观察整块重复vs分片重复的性能差异。本组场景不包含计算逻辑仅执行数据搬运操作。流式数据场景Case3-4 本组场景实现两个shape为[8192, 8192]的half类型矩阵相加z x y采用双缓冲Ping-Pong技术实现数据搬运与向量计算的流水线并行。通过对比l2_cache_mode0NORMALvsl2_cache_mode4DISABLE展示bypass对流式数据的优化效果。样例实现性能指标说明本章节性能数据在Ascend 950系列产品上采集将Ascend 950PR/Ascend 950DT简称为Ascend 950系列。采用不同的性能采集指令分别获取不同的性能指标msprof ./demo— 采集AI Core指令级耗时及占比MTE2/MTE3/Vector对应表1。msprof --ai-coreon --aic-metricsL2Cache ./demo— 采集L2 Cache读写命中/缺失计数对应表2。表1AI Core性能指标字段说明表字段名字段含义Task Duration(μs)整个任务执行的总时间算子执行时间以该参数为准。aiv_total_cyclesTask 执行总 cycle 数。aiv_mte2_time(μs)MTE2 类型指令GM → AI Core 搬运类指令耗时单位为 μs。aiv_mte2_ratioMTE2 类型指令的 cycle 数在 total cycle 数中的占比。aiv_mte3_time(μs)MTE3 类型指令UB → GM 搬运类指令耗时单位为 μs。aiv_mte3_ratioMTE3 类型指令的 cycle 数在 total cycle 数中的占比。aiv_vec_time(μs)vec 类型指令向量类运算指令耗时单位 μs。aiv_vec_ratiovec 类型指令的 cycle 数在 total cycle 数中的占用比。表2L2 Cache性能指标字段说明表字段名字段含义Task Duration(μs)整个任务执行的总时间。aiv_total_cyclesTask 执行总 cycle 数。aiv_write_cache_hit写 Cache 命中的次数。aiv_write_cache_miss_allocate写 Cache 缺失后重新分配缓存的次数。aiv_read_local_l2_hit读 Cache 命中的次数。aiv_read_local_l2_miss读 Cache 缺失次数。aiv_read_local_l2_victim读 Cache 未命中并触发 Cache 中数据被换出的次数。L2 Cache命中率 aiv_read_local_l2_hit / (aiv_read_local_l2_hit aiv_read_local_l2_miss aiv_read_local_l2_victim)数据复用模式图解Case1和Case2中数据在GM与UB之间的搬运模式如下Case1整块矩阵连续重复搬运4次GM 矩阵: [M, N] ┌─────────────────────────────── N ───────────────────────────────┐ │ 全部列一次搬完 │ └──────────────────────────────────────────────────────────────────┘ 启动全部 core按相同路径搬运完整矩阵: 第 1 轮: 全部 core 从 GM 读取完整矩阵 - UB 第 2 轮: 全部 core 再次读取完整矩阵 - UB 第 3 轮: 全部 core 再次读取完整矩阵 - UB 第 4 轮: 全部 core 再次读取完整矩阵 - UB 说明: 每轮工作集都是整块矩阵L2 Cache 难以完整保留上一轮数据Case2N方向切4份后每份连续重复搬运4次GM 矩阵: [M, N] ┌──────── N/4 ────────┬──────── N/4 ────────┬──────── N/4 ────────┬──────── N/4 ────────┐ │ 分片0 │ 分片1 │ 分片2 │ 分片3 │ └─────────────────────┴─────────────────────┴─────────────────────┴─────────────────────┘ 启动全部 core先把分片0的数据连续搬运 4 轮再处理下一个分片: 分片0: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 分片1: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 分片2: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 分片3: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 说明: 单个分片工作集更小连续重复访问时更容易保留在 L2 Cache 中Case1: 整块连续重复搬运4次 l2_cache_mode0NORMAL设计意图整块矩阵301.99MB大于L2 Cache容量约128MB每次完整矩阵搬运都会导致旧数据被换出L2命中率较低。与Case2分片重复对比说明分片策略控制工作集大小的重要性——即使启用L2 Cache如果单次工作集超出L2容量也必须通过分片策略来控制工作集大小。样例配置整块矩阵沿相同路径连续重复搬运4次。总搬运数据量301.99MB × 4 1207.96MB。Tile[64, 1024]单次asc_copy_gm2ub_align搬运131,072B。L2策略l2_cache_mode0NORMAL性能数据架构Scenario配置Task Duration(μs)aiv_total_cyclesaiv_time(μs)aiv_read_local_l2_hitaiv_read_local_l2_missaiv_read_local_l2_victim说明L2Cache命中率Ascend 950系列Case1Tensor[12288,12288]Tile[64,1024]Block Num64690.3872348218689.487315345231777672752整块矩阵按相同路径连续搬4次8.2%优化效果分析L2 Cache命中率仅为8.2%绝大多数重复访问仍需从GM读取。整块矩阵302MB远超L2 Cache容量约128MB启用L2 Cache收益极低。victim计数高达7,672,752说明上一轮缓存数据几乎全部被换出。原理说明每轮搬运完整矩阵时上一轮缓存在L2中的数据几乎全部被换出victim计数高达7,672,752下一轮重复访问时仍需从GM重新读取。每次miss都会触发Cache Line分配和旧数据换出操作这些无效的缓存管理额外消耗了L2控制器管理带宽降低了MTE2的搬运效率。性能优化建议当单次工作集远超L2容量时仅启用L2 Cache无法获得复用收益应通过分片策略将单次工作集控制在L2容量以内。Case2: N方向切4份 每份连续搬4次 l2_cache_mode0NORMAL设计意图对于需要多次重复读取的数据启用L2 Cache将首次读取的数据缓存起来后续重复访问直接从L2读取显著降低MTE2搬运耗时。输入矩阵301.99MB L2容量约128MB整块无法被完整缓存因此N方向切4份后每份约75.50MB每个分片可在一定范围内获得L2命中率提升。样例配置N方向切4份每个分片内连续重复搬运4次。总搬运数据量301.99MB × 4 1207.96MB。Tile[64, 1024]单次asc_copy_gm2ub_align搬运131,072B。L2策略l2_cache_mode0NORMAL性能数据架构Scenario配置Task Duration(μs)aiv_total_cyclesaiv_time(μs)aiv_read_local_l2_hitaiv_read_local_l2_missaiv_read_local_l2_victim说明L2Cache命中率Ascend 950系列Case2Tensor[12288,12288]Tile[64,1024]Block Num64350.9536233475350.0366687745286761720984N方向切4份每份连续搬4次74.8%优化效果分析L2 Cache命中率从8.2%Case1提升至74.8%接近理论极限75%4轮搬运中第1轮必miss第2~4轮理想情况下全部命中。Task Duration从690.38μs降低至350.95μs减少49.2%。victim计数从7,672,752降至1,720,984缓存颠簸显著减轻。原理说明整块矩阵302MB远超L2容量128MB无法被完整缓存。N方向切4份后单分片约75.5MB可在L2容量范围内被有效缓存。每个分片内连续重复访问时第2~4轮的数据直接从L2命中大幅减少GM读取次数。性能优化建议对于超L2容量的重复访问数据应先通过分片将单次工作集控制在L2容量以内再启用L2 Cache获得复用收益。Case3: Add双缓冲 l2_cache_mode0NORMAL设计意图Add算子的输入x、y均为流式数据每个元素只读一次采用双缓冲流水线并行。l2_cache_mode0NORMAL时MTE2将数据搬运到UB的同时会写入L2 Cache但数据不会被再次访问写入L2的操作是纯浪费的额外消耗了L2控制器管理带宽。样例配置矩阵[8192, 8192]half类型128MB每矩阵。均匀切分到64个AIV Core。dataCopyLen21760。L2策略l2_cache_mode0NORMAL性能数据Task Duration(μs)aiv_time(μs)aiv_vec_time(μs)aiv_vec_ratioaiv_scalar_time(μs)aiv_scalar_ratioaiv_mte2_time(μs)aiv_mte2_ratioaiv_mte3_time(μs)aiv_mte3_ratio240.01239.1383.140.3481.8150.008233.8690.978121.440.507优化效果分析MTE2搬运数据的同时写入L2 Cache浪费了L2控制器管理带宽aiv_mte2_time达到233.869μs占比97.8%。原理说明Add算子的输入x、y均为流式数据每个元素仅被访问一次后不再复用。l2_cache_mode0NORMAL会使MTE2在GM→UB搬运时额外执行L2 Cache写入操作这些写入对性能无帮助反而占用L2控制器管理带宽并污染L2 Cache空间。性能优化建议对于流式访问的数据应配置l2_cache_mode4DISABLE跳过L2 Cache写入省去不必要的cache管理开销。Case4: Add双缓冲 l2_cache_mode4DISABLE设计意图与Case3的区别仅在于asc_copy_gm2ub_align调用时传入l2_cache_mode4DISABLE模式代替l2_cache_mode0NORMAL模式。对于只读一次的流式数据禁用L2 Cache后MTE2直接将数据从GM搬运到UB避免了不必要的cache写开销并可避免流式数据占据L2空间。关键代码// Case 3l2_cache_mode0NORMAL和 Case 4l2_cache_mode4DISABLE // 唯一区别在于 l2_cache_mode 参数值 __aicore__ inline void ProcessDoubleBufferImpl(uint8_t l2CacheMode) { // ... asc_copy_gm2ub_align(xLocal, xGm startElement, 1, (uint32_t)(curLen * sizeof(half)), 0, 0, 0, l2CacheMode, 0, 0); asc_copy_gm2ub_align(yLocal, yGm startElement, 1, (uint32_t)(curLen * sizeof(half)), 0, 0, 0, l2CacheMode, 0, 0); // ... }L2策略l2_cache_mode4DISABLE性能数据Task Duration(μs)aiv_time(μs)aiv_vec_time(μs)aiv_vec_ratioaiv_scalar_time(μs)aiv_scalar_ratioaiv_mte2_time(μs)aiv_mte2_ratioaiv_mte3_time(μs)aiv_mte3_ratio172.996171.8182.4620.481.8010.01166.7520.97118.7230.109优化效果分析Task Duration从240.01μs降低至172.996μs减少27.9%。MTE2耗时从233.869μs降低至166.752μs减少28.7%。MTE3耗时从121.44μs降低至18.723μs减少84.6%。aiv_vec_time基本不变83.14μs → 82.462μs变化0.8%说明L2 Cache bypass不影响向量计算部分的耗时。原理说明l2_cache_mode4DISABLE跳过L2 Cache写入MTE2直接将数据从GM搬运到UB省去了不必要的cache写操作和Cache Line分配开销。性能优化建议对于数据量大且只读取一次的流式数据如Add、Mul等逐元素算子的输入建议在asc_copy_gm2ub_align中配置l2_cache_mode4DISABLE跳过不必要的cache写入提升MTE2搬运效率。优化要点总结优化手段核心原理适用场景L2 Cache bypass避免Cache污染减少开销流式访问只读一次启用L2 Cache利用L2 Cache将首次读取的数据缓存起来后续重复访问直接从L2读取访问L2 Cache带宽相较直接访问GM更大重复读取的数据分片后重复访问将重复访问限制在更小的数据范围内提高L2Cache命中机会复用的数据大小超过L2Cache容量L2 Cache Mode决策树该数据会被多次读取吗 ├── 是 → 使用 l2_cache_mode0NORMAL │ 单次工作集 L2 容量 │ └── 是 → 先分片再在每个分片内使用 l2_cache_mode0NORMAL └── 否 → 使用 l2_cache_mode4DISABLE流式数据 bypass编译运行在本样例根目录下执行如下步骤编译并执行样例。配置环境变量source ${install_path}/cann/set_env.sh说明${install_path}为 CANN 包安装目录。样例执行SCENARIO_NUM1 ASC_ARCHdav-3510 mkdir -p build cd build cmake -DSCENARIO_NUM$SCENARIO_NUM -DCMAKE_ASC_ARCHITECTURES$ASC_ARCH .. make -j python3 ../scripts/gen_data.py -scenarioNum $SCENARIO_NUM ./demo编译选项说明参数说明可选值默认值SCENARIO_NUM场景编号1-41CMAKE_ASC_RUN_MODE运行模式npu、simnpuCMAKE_ASC_ARCHITECTURESNPU 硬件架构dav-3510仅该架构支持dav-3510性能采集使用msprof工具获取详细性能数据msprof ./demo # 采集 MTE2/MTE3/Vector 性能数据字段含义见表1。 msprof --ai-coreon --aic-metricsL2Cache ./demo # 采集 L2 Cache 性能数据字段含义见表2。采集后会在当前目录生成PROF_前缀目录性能汇总文件位于mindstudio_profiler_output目录下。PROF_xxxx_XXXXXX ├── device_{id} ├── host ├── mindstudio_profiler_log └── mindstudio_profiler_output ├── msprof_*.json ├── op_summary_*.csv └── README.txt查看具体的性能分析结果# 查看 Task Duration 以及各项数据 cat ./PROF_*/mindstudio_profiler_output/op_summary_*.csv【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
CANN/asc-devkit L2缓存模式最佳实践
L2 Cache Mode 最佳实践样例【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit概述MTE2将数据从Global MemoryGM搬运到Unified BufferUB时可通过asc_copy_gm2ub_align接口的l2_cache_mode参数本样例使用基于指针的C语言编程显式配置数据在L2 Cache中的管理策略。本样例说明复用数据和流式数据两大类场景下如何选择合适的L2 Cache模式来优化MTE2搬运性能以及在启用L2 Cache的前提下如何通过分片策略提升L2 Cache命中率。复用数据场景数据需多次读取Case1: 整块重复搬4次l2_cache_mode0NORMAL → 整块数据远超L2容量命中率极低展示未分片时的性能瓶颈。 Case2: N方向切4份每份连续搬4次l2_cache_mode0NORMAL → 分片后单份工作集降至L2容量以内命中率提升。流式数据场景数据只读一次Case3: Add 双缓冲l2_cache_mode0NORMAL基准。 Case4: 同Case3但将l2_cache_mode设为4DISABLE跳过L2 Cache → 与Case3对比。本样例支持的产品及CANN软件版本产品CANN软件版本Ascend 950PR/Ascend 950DT CANN 9.1.0目录结构介绍├── set_l2_cache_mode │ ├── scripts │ │ └── gen_data.py // 输入数据和真值数据生成脚本文件 │ ├── CMakeLists.txt // 编译工程文件 │ ├── set_l2_cache_mode.asc // 样例入口kernel 调用 main 函数 │ ├── set_l2_cache_mode.h // Kernel 实现DataCopyRepeat Add │ ├── data_utils.h // 数据读入写出函数 │ ├── README.md // 样例说明文档 │ └── README_en.md // 样例说明文档英文样例描述C-API的GM→UB搬运接口通过入参l2_cache_mode来控制本次搬运数据在L2 Cache中的管理策略取值及含义详见asc_copy_gm2ub_align接口说明。围绕上述两类场景本样例设计了4个Case进行对比验证数据复用场景Case1-2 本组场景输入为half类型二维矩阵shape为[12288, 12288]。使用asc_copy_gm2ub_align将数据从GM搬运到UB通过对比不同搬运策略下的L2 Cache命中率观察整块重复vs分片重复的性能差异。本组场景不包含计算逻辑仅执行数据搬运操作。流式数据场景Case3-4 本组场景实现两个shape为[8192, 8192]的half类型矩阵相加z x y采用双缓冲Ping-Pong技术实现数据搬运与向量计算的流水线并行。通过对比l2_cache_mode0NORMALvsl2_cache_mode4DISABLE展示bypass对流式数据的优化效果。样例实现性能指标说明本章节性能数据在Ascend 950系列产品上采集将Ascend 950PR/Ascend 950DT简称为Ascend 950系列。采用不同的性能采集指令分别获取不同的性能指标msprof ./demo— 采集AI Core指令级耗时及占比MTE2/MTE3/Vector对应表1。msprof --ai-coreon --aic-metricsL2Cache ./demo— 采集L2 Cache读写命中/缺失计数对应表2。表1AI Core性能指标字段说明表字段名字段含义Task Duration(μs)整个任务执行的总时间算子执行时间以该参数为准。aiv_total_cyclesTask 执行总 cycle 数。aiv_mte2_time(μs)MTE2 类型指令GM → AI Core 搬运类指令耗时单位为 μs。aiv_mte2_ratioMTE2 类型指令的 cycle 数在 total cycle 数中的占比。aiv_mte3_time(μs)MTE3 类型指令UB → GM 搬运类指令耗时单位为 μs。aiv_mte3_ratioMTE3 类型指令的 cycle 数在 total cycle 数中的占比。aiv_vec_time(μs)vec 类型指令向量类运算指令耗时单位 μs。aiv_vec_ratiovec 类型指令的 cycle 数在 total cycle 数中的占用比。表2L2 Cache性能指标字段说明表字段名字段含义Task Duration(μs)整个任务执行的总时间。aiv_total_cyclesTask 执行总 cycle 数。aiv_write_cache_hit写 Cache 命中的次数。aiv_write_cache_miss_allocate写 Cache 缺失后重新分配缓存的次数。aiv_read_local_l2_hit读 Cache 命中的次数。aiv_read_local_l2_miss读 Cache 缺失次数。aiv_read_local_l2_victim读 Cache 未命中并触发 Cache 中数据被换出的次数。L2 Cache命中率 aiv_read_local_l2_hit / (aiv_read_local_l2_hit aiv_read_local_l2_miss aiv_read_local_l2_victim)数据复用模式图解Case1和Case2中数据在GM与UB之间的搬运模式如下Case1整块矩阵连续重复搬运4次GM 矩阵: [M, N] ┌─────────────────────────────── N ───────────────────────────────┐ │ 全部列一次搬完 │ └──────────────────────────────────────────────────────────────────┘ 启动全部 core按相同路径搬运完整矩阵: 第 1 轮: 全部 core 从 GM 读取完整矩阵 - UB 第 2 轮: 全部 core 再次读取完整矩阵 - UB 第 3 轮: 全部 core 再次读取完整矩阵 - UB 第 4 轮: 全部 core 再次读取完整矩阵 - UB 说明: 每轮工作集都是整块矩阵L2 Cache 难以完整保留上一轮数据Case2N方向切4份后每份连续重复搬运4次GM 矩阵: [M, N] ┌──────── N/4 ────────┬──────── N/4 ────────┬──────── N/4 ────────┬──────── N/4 ────────┐ │ 分片0 │ 分片1 │ 分片2 │ 分片3 │ └─────────────────────┴─────────────────────┴─────────────────────┴─────────────────────┘ 启动全部 core先把分片0的数据连续搬运 4 轮再处理下一个分片: 分片0: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 分片1: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 分片2: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 分片3: 第 1 轮从 GM 读取第 2~4 轮优先从 L2 Cache 读取 说明: 单个分片工作集更小连续重复访问时更容易保留在 L2 Cache 中Case1: 整块连续重复搬运4次 l2_cache_mode0NORMAL设计意图整块矩阵301.99MB大于L2 Cache容量约128MB每次完整矩阵搬运都会导致旧数据被换出L2命中率较低。与Case2分片重复对比说明分片策略控制工作集大小的重要性——即使启用L2 Cache如果单次工作集超出L2容量也必须通过分片策略来控制工作集大小。样例配置整块矩阵沿相同路径连续重复搬运4次。总搬运数据量301.99MB × 4 1207.96MB。Tile[64, 1024]单次asc_copy_gm2ub_align搬运131,072B。L2策略l2_cache_mode0NORMAL性能数据架构Scenario配置Task Duration(μs)aiv_total_cyclesaiv_time(μs)aiv_read_local_l2_hitaiv_read_local_l2_missaiv_read_local_l2_victim说明L2Cache命中率Ascend 950系列Case1Tensor[12288,12288]Tile[64,1024]Block Num64690.3872348218689.487315345231777672752整块矩阵按相同路径连续搬4次8.2%优化效果分析L2 Cache命中率仅为8.2%绝大多数重复访问仍需从GM读取。整块矩阵302MB远超L2 Cache容量约128MB启用L2 Cache收益极低。victim计数高达7,672,752说明上一轮缓存数据几乎全部被换出。原理说明每轮搬运完整矩阵时上一轮缓存在L2中的数据几乎全部被换出victim计数高达7,672,752下一轮重复访问时仍需从GM重新读取。每次miss都会触发Cache Line分配和旧数据换出操作这些无效的缓存管理额外消耗了L2控制器管理带宽降低了MTE2的搬运效率。性能优化建议当单次工作集远超L2容量时仅启用L2 Cache无法获得复用收益应通过分片策略将单次工作集控制在L2容量以内。Case2: N方向切4份 每份连续搬4次 l2_cache_mode0NORMAL设计意图对于需要多次重复读取的数据启用L2 Cache将首次读取的数据缓存起来后续重复访问直接从L2读取显著降低MTE2搬运耗时。输入矩阵301.99MB L2容量约128MB整块无法被完整缓存因此N方向切4份后每份约75.50MB每个分片可在一定范围内获得L2命中率提升。样例配置N方向切4份每个分片内连续重复搬运4次。总搬运数据量301.99MB × 4 1207.96MB。Tile[64, 1024]单次asc_copy_gm2ub_align搬运131,072B。L2策略l2_cache_mode0NORMAL性能数据架构Scenario配置Task Duration(μs)aiv_total_cyclesaiv_time(μs)aiv_read_local_l2_hitaiv_read_local_l2_missaiv_read_local_l2_victim说明L2Cache命中率Ascend 950系列Case2Tensor[12288,12288]Tile[64,1024]Block Num64350.9536233475350.0366687745286761720984N方向切4份每份连续搬4次74.8%优化效果分析L2 Cache命中率从8.2%Case1提升至74.8%接近理论极限75%4轮搬运中第1轮必miss第2~4轮理想情况下全部命中。Task Duration从690.38μs降低至350.95μs减少49.2%。victim计数从7,672,752降至1,720,984缓存颠簸显著减轻。原理说明整块矩阵302MB远超L2容量128MB无法被完整缓存。N方向切4份后单分片约75.5MB可在L2容量范围内被有效缓存。每个分片内连续重复访问时第2~4轮的数据直接从L2命中大幅减少GM读取次数。性能优化建议对于超L2容量的重复访问数据应先通过分片将单次工作集控制在L2容量以内再启用L2 Cache获得复用收益。Case3: Add双缓冲 l2_cache_mode0NORMAL设计意图Add算子的输入x、y均为流式数据每个元素只读一次采用双缓冲流水线并行。l2_cache_mode0NORMAL时MTE2将数据搬运到UB的同时会写入L2 Cache但数据不会被再次访问写入L2的操作是纯浪费的额外消耗了L2控制器管理带宽。样例配置矩阵[8192, 8192]half类型128MB每矩阵。均匀切分到64个AIV Core。dataCopyLen21760。L2策略l2_cache_mode0NORMAL性能数据Task Duration(μs)aiv_time(μs)aiv_vec_time(μs)aiv_vec_ratioaiv_scalar_time(μs)aiv_scalar_ratioaiv_mte2_time(μs)aiv_mte2_ratioaiv_mte3_time(μs)aiv_mte3_ratio240.01239.1383.140.3481.8150.008233.8690.978121.440.507优化效果分析MTE2搬运数据的同时写入L2 Cache浪费了L2控制器管理带宽aiv_mte2_time达到233.869μs占比97.8%。原理说明Add算子的输入x、y均为流式数据每个元素仅被访问一次后不再复用。l2_cache_mode0NORMAL会使MTE2在GM→UB搬运时额外执行L2 Cache写入操作这些写入对性能无帮助反而占用L2控制器管理带宽并污染L2 Cache空间。性能优化建议对于流式访问的数据应配置l2_cache_mode4DISABLE跳过L2 Cache写入省去不必要的cache管理开销。Case4: Add双缓冲 l2_cache_mode4DISABLE设计意图与Case3的区别仅在于asc_copy_gm2ub_align调用时传入l2_cache_mode4DISABLE模式代替l2_cache_mode0NORMAL模式。对于只读一次的流式数据禁用L2 Cache后MTE2直接将数据从GM搬运到UB避免了不必要的cache写开销并可避免流式数据占据L2空间。关键代码// Case 3l2_cache_mode0NORMAL和 Case 4l2_cache_mode4DISABLE // 唯一区别在于 l2_cache_mode 参数值 __aicore__ inline void ProcessDoubleBufferImpl(uint8_t l2CacheMode) { // ... asc_copy_gm2ub_align(xLocal, xGm startElement, 1, (uint32_t)(curLen * sizeof(half)), 0, 0, 0, l2CacheMode, 0, 0); asc_copy_gm2ub_align(yLocal, yGm startElement, 1, (uint32_t)(curLen * sizeof(half)), 0, 0, 0, l2CacheMode, 0, 0); // ... }L2策略l2_cache_mode4DISABLE性能数据Task Duration(μs)aiv_time(μs)aiv_vec_time(μs)aiv_vec_ratioaiv_scalar_time(μs)aiv_scalar_ratioaiv_mte2_time(μs)aiv_mte2_ratioaiv_mte3_time(μs)aiv_mte3_ratio172.996171.8182.4620.481.8010.01166.7520.97118.7230.109优化效果分析Task Duration从240.01μs降低至172.996μs减少27.9%。MTE2耗时从233.869μs降低至166.752μs减少28.7%。MTE3耗时从121.44μs降低至18.723μs减少84.6%。aiv_vec_time基本不变83.14μs → 82.462μs变化0.8%说明L2 Cache bypass不影响向量计算部分的耗时。原理说明l2_cache_mode4DISABLE跳过L2 Cache写入MTE2直接将数据从GM搬运到UB省去了不必要的cache写操作和Cache Line分配开销。性能优化建议对于数据量大且只读取一次的流式数据如Add、Mul等逐元素算子的输入建议在asc_copy_gm2ub_align中配置l2_cache_mode4DISABLE跳过不必要的cache写入提升MTE2搬运效率。优化要点总结优化手段核心原理适用场景L2 Cache bypass避免Cache污染减少开销流式访问只读一次启用L2 Cache利用L2 Cache将首次读取的数据缓存起来后续重复访问直接从L2读取访问L2 Cache带宽相较直接访问GM更大重复读取的数据分片后重复访问将重复访问限制在更小的数据范围内提高L2Cache命中机会复用的数据大小超过L2Cache容量L2 Cache Mode决策树该数据会被多次读取吗 ├── 是 → 使用 l2_cache_mode0NORMAL │ 单次工作集 L2 容量 │ └── 是 → 先分片再在每个分片内使用 l2_cache_mode0NORMAL └── 否 → 使用 l2_cache_mode4DISABLE流式数据 bypass编译运行在本样例根目录下执行如下步骤编译并执行样例。配置环境变量source ${install_path}/cann/set_env.sh说明${install_path}为 CANN 包安装目录。样例执行SCENARIO_NUM1 ASC_ARCHdav-3510 mkdir -p build cd build cmake -DSCENARIO_NUM$SCENARIO_NUM -DCMAKE_ASC_ARCHITECTURES$ASC_ARCH .. make -j python3 ../scripts/gen_data.py -scenarioNum $SCENARIO_NUM ./demo编译选项说明参数说明可选值默认值SCENARIO_NUM场景编号1-41CMAKE_ASC_RUN_MODE运行模式npu、simnpuCMAKE_ASC_ARCHITECTURESNPU 硬件架构dav-3510仅该架构支持dav-3510性能采集使用msprof工具获取详细性能数据msprof ./demo # 采集 MTE2/MTE3/Vector 性能数据字段含义见表1。 msprof --ai-coreon --aic-metricsL2Cache ./demo # 采集 L2 Cache 性能数据字段含义见表2。采集后会在当前目录生成PROF_前缀目录性能汇总文件位于mindstudio_profiler_output目录下。PROF_xxxx_XXXXXX ├── device_{id} ├── host ├── mindstudio_profiler_log └── mindstudio_profiler_output ├── msprof_*.json ├── op_summary_*.csv └── README.txt查看具体的性能分析结果# 查看 Task Duration 以及各项数据 cat ./PROF_*/mindstudio_profiler_output/op_summary_*.csv【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考