资讯动态

CANN shmem 性能测试:ascendc_perftest 与 AscendC::DataCopy / shmem put-get 接口对比实测指南

发布时间:2026/9/19 23:35:00 来源:尧图企业网站定制
CANN shmem 性能测试ascendc_perftest 与 AscendC::DataCopy / shmem put-get 接口对比实测指南【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库基于OpenSHMEM 标准协议实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem本指南聚焦 CANN shmem 仓库中ascendc_perftest参数化性能测试示例完整讲解它的设计目标、编译方式、命令行参数、CSV 输出格式与源码级实现原理帮助你用一套命令体系对比AscendC::DataCopy与shmem put/get在跨设备、跨内存类型UB/GM场景下的带宽与耗时差异为算子与通信链路的性能优化提供量化依据。示例定位为什么需要对比 DataCopy 与 shmem put/getascendc_perftest是 CANN shmem 仓库 examples/shmem_perftest 参数化性能测试集合中的子示例之一它的核心定位是测试 AscendC::DataCopy 接口的性能并可与 shmem 的 put/get 接口进行比较。在多机多卡内存通信场景中数据搬运存在两条技术路线AscendC::DataCopy基于 Ascend C 编程框架的 MTEMemory Transfer Engine数据搬运接口开发者通常用它完成核内 UBUnified Buffer统一缓冲区与 GMGlobal Memory全局内存之间的数据搬入搬出shmem put/get 接口CANN shmem 基于 OpenSHMEM 标准协议提供的远程内存访问RMA接口能够跨设备甚至跨机直接读写远端内存。两条路线在数据传输路径、硬件引擎占用、同步开销上各有差异。通过本示例的对比测试用户可以了解在不同核数、不同数据量、不同数据类型下哪种传输方式表现更优从而在实际算子或通信场景中做出更合理的选择。需要特别说明的是暂不支持 Ascend950当前版本不支持在 Ascend950 平台配套编译运行本示例。本示例测试结果仅做参考性能以实际场景为准。测试目的本示例主要用于比较以下两种数据传输方式的性能AscendC::DataCopy基于 Ascend C 的数据传输接口shmem 的 put/get 接口共享内存的数据传输接口。通过对比测试结果可以了解在不同场景下哪种数据传输方式具有更好的性能表现为通信与算子侧的数据搬运优化提供参考。功能特性支持的测试类型测试类型说明put测试跨设备 PUT 操作的性能从本地设备内存传输到远端设备内存get测试跨设备 GET 操作的性能从远端设备内存传输到本地设备内存ub2gm_local测试本地设备 UB 到 GM 的数据传输性能ub2gm_remote测试远端设备 UB 到 GM 的数据传输性能gm2ub_local测试本地设备 GM 到 UB 的数据传输性能gm2ub_remote测试远端设备 GM 到 UB 的数据传输性能all运行所有测试类型其中put/get为跨设备路径与 shmem 的 put/get 接口对标ub2gm_*/gm2ub_*四个模式则用于单独考察 AscendC::DataCopy 在 UB 与 GM 之间的搬运性能本地/远端两个维度。支持的数据类型浮点型float有符号整型int8、int16、int32、int64无符号整型uint8、uint16、uint32、uint64字符型charall测试所有数据类型其他特性✅ 可配置核数范围默认 32 核✅ 可配置数据量范围支持 2 的幂次方✅ 可指定设备 ID 进行跨设备测试✅ 可设置循环次数以获得稳定性能数据✅ 自动数据正确性验证PUT/GET✅ 生成 CSV 格式性能报告✅ 支持批量测试all 选项✅ 支持自动绘制性能图表与生成 Markdown 报告-a plot/-a md编译说明在 shmem 仓库根目录下编译示例有两种方式# 方法1使用 build.sh 脚本编译所有示例 bash scripts/build.sh -examples # 方法2手动编译 mkdir -p build cd build cmake -DUSE_EXAMPLESON .. source /usr/local/Ascend/ascend-toolkit/set_env.sh make -j编译说明如下-examples是 scripts/build.sh 提供的编译选项之一用于在构建产物中一并编译全部 examples编译脚本本身位于 scripts/build.sh。示例的构建由 examples/shmem_perftest/ascendc_perftest/CMakeLists.txt 通过aclshmem_add_collective_example(ascendc_perftest)纳入构建体系并将../include加入头文件搜索路径。编译完成后可执行文件路径为build/bin/ascendc_perftest由 examples/shmem_perftest/ascendc_perftest/run.sh 中的EXEC_BIN${PROJECT_ROOT}/build/bin/ascendc_perftest可知。使用方法基本用法# 进入示例目录 cd examples/shmem_perftest/ascendc_perftest # 运行测试脚本 source /usr/local/Ascend/ascend-toolkit/set_env.sh ./run.sh [选项]run.sh会自动定位仓库根目录下的build/lib与ASCEND_HOME_PATH/lib64并加入LD_LIBRARY_PATH因此无需手工设置动态库路径。命令行参数下表汇总了 examples/shmem_perftest/ascendc_perftest/run.sh 与 main.cpp 中解析的全部参数参数缩写描述默认值--test-type type-t type测试类型 (put/get/ub2gm_local/ub2gm_remote/gm2ub_local/gm2ub_remote/all)put--datatype type-d type数据类型 (float/int8/int16/int32/int64/uint8/uint16/uint32/uint64/char/all)float--block-size size-b size设置单个核数32--block-range min max-设置连续核数范围32-32--block-list b1,b2,...-设置离散核数列表如2,4,6,8---exponent exponent-e exponent设置数据量的幂数 (2^exponent)---exponent-range min max-设置数据量的幂数范围3-20--device1 id-设置设备1 ID1--device2 id-设置设备2 ID2--loop-count count-设置循环次数1000--ub-size size-设置 UB size(KB)16-a/--analyse mode-分析模式none只出 CSV/plot只出图/md出图 Markdown 报告none参数解析细节说明源自 main.cpp-b与-e同时设置最小值和最大值而--block-range/--exponent-range用于指定连续区间。--block-list支持逗号分隔的离散核数列表如2,4,6,8解析逻辑parse_block_list位于 examples/utils/utils.h要求每个核数为正整数指定后优先于-b与--block-range。若未指定--block-listmain 中会将[min_block_size, max_block_size]展开为连续的核数序列。传入非法的-t或-d时run.sh与main.cpp都会打印用法并退出。使用示例1. 测试单个操作类型和数据类型# 测试PUT操作float类型32核数据量从2^8到2^20字节1000次循环 ./run.sh -t put -d float --block-size 32 --exponent-range 8 20 --device1 1 --device2 2 --loop-count 1000 # 测试GET操作int32类型 ./run.sh -t get -d int32 --block-size 32 --exponent-range 8 20 --device1 1 --device2 2 --loop-count 10002. 测试所有操作类型指定数据类型# 测试所有操作类型PUT/GET/UB2GM/GM2UB使用float数据类型 ./run.sh -t all -d float --block-size 32 --exponent-range 8 20 --device1 1 --device2 2 --loop-count 10003. 测试所有数据类型指定操作类型# 测试PUT操作使用所有数据类型 ./run.sh -t put -d all --block-size 32 --exponent-range 8 20 --device1 1 --device2 2 --loop-count 10004. 测试所有操作类型和数据类型# 测试所有操作类型和所有数据类型 ./run.sh -t all -d all --block-size 32 --exponent-range 8 20 --device1 1 --device2 2 --loop-count 1000当-t all与-d all组合时脚本会展开为 6 种测试类型 × 10 种数据类型共 60 组测试由 run.sh 中的ALL_TEST_TYPES与ALL_DATATYPES数组决定。5. 测试指定核数# 在指定核数2、4、6、8、16核测试所有操作类型和所有数据类型 ./run.sh -t all -d all --block-list 2,4,6,8,16 --exponent-range 8 20 --device1 1 --device2 2 --loop-count 10006. 使用默认参数运行# 使用默认参数运行put测试 ./run.sh # 运行所有测试类型 ./run.sh -t all7. 图形化数据# 使用 perf_data_process.py -d 传入csv数据存储路径图形化结果将存储在csv存储路径下picture文件夹下。 python examples/utils/perf_data_process.py -d outputexamples/utils/perf_data_process.py 支持-d/--dir目录与-c/--csv-path单文件两种输入可选-u/--ubsize、-s/--coresize过滤、--no-plot、--no-markdown控制输出。它会为每个 CSV 生成按 Blocks 分组的UBsize 对比图*_UBsize_compare.png按 UBsize 分组的Blocks 对比图*_Core_compare.png最大带宽热力图*_bandwidth_max_heatmap.png平均带宽热力图数据量 1MB*_bandwidth_mean_heatmap.png。若使用-a plot/-a md参数运行run.sh脚本会在测试完成后自动调用该绘图脚本plot模式仅出图md模式同时生成performance_report.md报告包含性能数据表格与图片引用。输出说明CSV 文件格式测试运行后会在当前目录下生成output文件夹其中包含测试结果的 CSV 文件文件名格式为{rank}_{test_type}_{data_type}.csv例如0_put_float.csv- PUT 操作float 类型0_get_int32.csv- GET 操作int32 类型0_ub2gm_local_float.csv- 本地 UB 到 GM 操作float 类型0_gm2ub_remote_int32.csv- 远端 GM 到 UB 操作int32 类型CSV 由 examples/utils/utils.h 的write_csv工具写出在 main.cpp 中以output/0_{test_type}_{data_type}.csv命名落盘。CSV 文件内容CSV 文件包含以下字段字段描述DataSize/B数据大小字节Npus使用的 NPU 数量Blocks核数UBsize/KBUB 大小KBBandwidth/GB/s带宽大小GB/sCoreMaxTime/us最大核时间微秒SingleCoreTime/us单核时间微秒从源码看main.cpp实际写入前 6 个基础字段后还会按核序追加每个核的平均耗时列每核一列因此 CSV 行数长度为6 Blocks。绘图脚本 perf_data_process.py 只读取前 6 列用于画图。源码实现解析一次测试到底测量了什么主流程Host 侧main.cpp 的run_rma_performance_test完成了完整的测试生命周期环境初始化aclInit→aclrtSetDevice(device1/device2)→ 通过aclrtDeviceEnablePeerAccess使两卡互相使能 Peer Access并创建 stream构造核数 × 数据量测试矩阵外层遍历block_sizes内层遍历2^min_exp到2^max_exp的幂次数据量内存分配与数据填充两卡各aclrtMalloc一块设备内存Host 侧生成两份不同的数据源数据以i datasize填充目标初始数据以i datasize 1填充保证初始内容与源不同便于验证调用设备侧内核device_perftest_demo(block_dim, stream, d1_ptr, d0_ptr, time_gva, elements, test_type, loop_count, data_type, ub_size)计时回收与带宽计算从设备侧拷回每核耗时计算最大核时间并按公式Bandwidth(GB/s) datasize × block_size / max_core_time × 10^6 / 1024^3换算带宽数据验证与 CSV 落盘。设备侧内核Device 侧ascendc_perftest_kernel.cpp 中为 10 种数据类型 × 6 种测试模式分别定义了独立内核通过DEFINE_RMA_OPERATION_KERNEL_FOR_TYPE宏批量展开见文件第 490-525 行并由DISPATCH_RMA_OPERATION_FOR_ALL_TYPES按枚举分派。各模式的内核实现rma_operation_*_impl遵循统一的测时框架数据切分每个核搬运的 tile 长度由elements / GetBlockNum()决定核内偏移使用offset block_size 512 ? 512 / sizeof(T) : block_size / sizeof(T)保证每核至少 512 字节对齐的数据区间UB 分块tiling单核单次数据量超过ub_size_kb × 1024时按repeat_times分多次DataCopyPad搬运剩余remain单独处理预热与计时固定先执行warmup 100次预热再执行loop_count次正式测试仅累加正式阶段的GetSystemCycle()周期差耗时通过all_times / cycle2us / loop_test换算为微秒并写入time_gm BlockIdx * 16事件同步各类模式使用AscendC::SetFlag/WaitFlag的硬事件如S_MTE2、MTE2_MTE3、MTE3_S等保证 MTE 流水线之间的搬运顺序。从内核结构可以推断各模式的数据流向ascendc_putGM(本地 d0) → UB → GM(远端 d1)即 DataCopy 模拟的跨设备 PUT 路径ascendc_getGM(远端 d1) → UB → GM(本地 d0)对应跨设备 GET 路径ub2gm_*/gm2ub_*仅执行单段UB ⇄ GM搬运用于测量 DataCopy 在单一方向上的原始能力。数据类型分发与枚举定义测试类型与数据类型枚举定义在 examples/utils/perftest_common_types.h 中ascendc_mode_t、perf_data_type_t类型字符串到枚举、类型字节大小的映射在 examples/shmem_perftest/include/mte_perftest_common.h 中get_data_type/get_datatype_size/DISPATCH_BY_TYPE。这些公共头文件同时被 shmem_perftest 下的多个子示例复用。数据验证测试过程中仅 PUT/GET 会自动进行数据正确性验证PUT 操作验证源数据是否完整传输到目标地址对比测试后d1的目标区与测试前d0源区每个核的首值GET 操作验证从远端读取的数据是否正确对比测试后d0源区与测试前d1目标区每个核的首值。ub2gm_*/gm2ub_*模式会打印 Verification skipped 跳过校验。验证成功时显示[Verification] SUCCESS: All cores first values transferred correctly!验证失败时显示[Verification] FAILED: At least one cores first value was not transferred correctly!验证逻辑位于 main.cpp对比粒度为每个核数据区间block_idx * offset的首个元素。注意事项环境配置运行前请确保已正确设置 Ascend 环境变量source /usr/local/Ascend/ascend-toolkit/set_env.sh设备配置确保指定的设备 IDdevice1 和 device2可用且支持 Peer Accessmain 中会调用aclrtDeviceEnablePeerAccess不支持时测试无法进行。数据量计算测试数据量的计算方式为2^exponent字节--exponent-range 8 20表示从 256B 测到 1MB。参数范围核数范围不能大于设备最大值实际核数不能超过设备可用核数否则内核elements / GetBlockNum()切分无意义或执行失败。内存要求大数据量测试需要足够的设备内存设备内存按offset × block_size × sizeof(T)全量分配且两卡各一份。数据类型支持某些数据类型如 uint64、char可能在特定场景下存在限制。性能稳定性建议使用较大的循环次数如 1000 次以获得稳定的性能数据内核本身会先做 100 次预热warmup 100正式计时只累加loop_count次。平台限制本示例不支持 Ascend950 平台编译运行。性能分析建议对比不同测试类型put/get/ub2gm_local/ub2gm_remote/gm2ub_local/gm2ub_remote的性能差异定位跨设备路径与单段搬运路径的差距来源。对比不同数据类型的性能表现观察小位宽类型如 int8/char与 32/64 bit 类型在带宽上的差异。根据实际硬件配置调整核数参数观察性能随核数扩展的变化寻找带宽饱和点。针对不同的数据量范围分析性能瓶颈小数据量通常受固定开销事件同步、启动延迟主导大数据量则更接近引擎峰值带宽。结合测试结果选择最适合实际应用场景的数据传输方式和数据类型。对比本地操作_local和远端操作_remote的性能差异评估跨设备访问的额外开销。使用--block-list或--block-range配合--ub-size做组合扫描再用perf_data_process.py生成热力图快速找到「核数 × UB size」的最优组合。故障排查常见问题设备不可用错误错误: 设备ID无效解决方案使用npu-smi info检查可用设备确保 device1 和 device2 参数正确。内存分配失败错误: aclrtMalloc failed解决方案减小数据量范围--exponent-range的上限或核数确保设备有足够内存。Peer Access 失败错误: aclrtDeviceEnablePeerAccess failed解决方案确保两个设备之间支持 Peer Access检查卡间拓扑与驱动配置。数据验证失败[Verification] FAILED: Data mismatch解决方案检查设备状态可能需要重置设备或重新运行测试。与其他子示例的关系ascendc_perftest是 examples/shmem_perftest 测试集合的一部分。该集合还包含测量 shmem MTE 引擎的mte_perftest、SDMA put/get 的sdma_perftest、UDMA 低阶接口的udma_perftest仅 Ascend950、RDMA 低阶接口的rdma_perftest需-enable_rdma编译以及 SIMT RMA 相关子示例。如果需要将 AscendC::DataCopy 与 shmem 各引擎做横向对比可以通过外层run.sh -m all统一驱动多个子示例或逐个进入子目录运行各子示例的独有参数与约束以其自身 README 为准。小结ascendc_perftest提供了一条从参数配置 → 自动测时 → 数据校验 → CSV/图表报告的完整性能对比链路。通过它的六种测试类型、十种数据类型与灵活的核数/数据量扫描能力开发者可以在 CANN shmem 生态内快速量化 AscendC::DataCopy 与 shmem put/get 在跨设备数据搬运上的性能差异并据此做出数据传输方案与优化方向的选择。需要注意的是任何测试结果都应结合真实应用场景验证避免以微基准结论直接替代业务实测。【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库基于OpenSHMEM 标准协议实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价