样例介绍
本样例展示在 SIMD 与 SIMT 混合编译模式下,如何对 SIMT 远程内存访问(RMA)接口进行性能测试(Performance Test)。
测试用于评估单机两卡间 Device-to-Device 的 gm2gm(global memory 到 global memory)数据传输能力,覆盖单向的 put 与 get 操作,并输出带宽与时延统计。
测试模型
测试固定使用两张卡,PE 号分别为 0 和 1:
- Active PE(PE 0):所有通信操作(
put/get)的发起方。 - Passive PE(PE 1):通信的对端,不主动发起操作。
两种操作的数据流向与校验方分别为:
| 操作 | 数据流向 | 校验方 |
|---|---|---|
put |
Active PE 的对称内存 → Passive PE 的对称内存 | Passive PE |
get |
Passive PE 的对称内存 → Active PE 的对称内存 | Active PE |
性能测试方法
为获得贴近真实的带宽与时延、避免数据缓存(Data Cache)命中导致结果虚高,以及方便实现,本样例采用以下设计:
- 仅 Active PE 发起、源与目的同址:
put/get是单边(one-sided)操作,全部由 Active PE 发起,Passive PE 仅作为远端对象、不参与计算(两卡通过 host 侧 barrier 同步)。每次传输的源地址与目的地址是同一个对称内存偏移,数据在两卡的相同偏移之间搬运。 - 预热与多轮取均值:单次测量会先执行
warmup_loops次传输进行预热(不计入统计),再执行loops次传输进行采样并取平均,以排除冷启动的影响。 - 逻辑段与逻辑环:每个 Core 物理上分配一块 256KB 的对称内存。设单次传输大小为 XX 字节、使用 NN 个 Core,定义每个 Core 的逻辑段大小为 L=min(256KB, (warmup_loops+loops)×X)L = \min(256\text{KB},\ (warmup\_loops + loops) \times X)(且不小于 XX,并保证为 XX 的整数倍)。NN 个逻辑段首尾相接,构成一个大小为 N×LN \times L 的逻辑环,Core jj 的逻辑段起始于环内偏移 j×Lj \times L。
- 滑动窗口遍历:第 ii 次迭代时,所有 Core 共同构成一个滑动窗口,窗口整体在环内的起点为 (i×X) mod (N×L)(i \times X) \bmod (N \times L)。Core jj 本次传输的目标偏移为 (i×X+j×L) mod (N×L)\big(i \times X + j \times L\big) \bmod (N \times L),即各 Core 在环上彼此错开一个逻辑段、各自传输一段长 XX 的数据。窗口每轮前进 XX 字节并在环内回绕。由于 X≤LX \le L,同一轮内各 Core 的数据段互不重叠;迭代之间由
SyncAll保证不冲突。 - 避免缓存命中:连续传输的地址不断前移,使其尽量落在不同缓存行上;当总传输量较小时逻辑环只占用刚好够用的空间,较大时按 256KB 上限循环复用,从而避免数据缓存命中抬高带宽读数。校验时按同样的逻辑段布局逐段比对(每段前 LL 字节),与实际写入的区域完全一致。
源文件宏定义配置
部分测试维度通过 main.cpp 开头的常量定义控制。在编译前可直接修改这些常量来改变底层接口的调用行为或数据位宽:
| 常量定义 | 含义与作用 | 可选值 / 默认值 |
|---|---|---|
VF_TYPE |
指令计算模式框架。 | SIMT(默认)、SIMD |
OP_TYPE |
性能测试执行的具体操作。 | PUT(默认)、GET、NONE(仅以 count = 0 调用接口,测量接口调用开销而不传输实际数据) |
DATA_SIZE |
所调用 RMA 底层接口的数据位宽(单位:bit)。修改后会切换到对应位宽的读写接口(如 aclshmemx_get32_block 切换为 aclshmemx_get64_block)。 |
8、16、32(默认)、64 |
THREAD_COUNT |
SIMT 模式下单 Core 启动的线程数,决定向量指令流的并发规模。 | 默认 1024 |
提示:修改上述常量后,需重新回到根目录执行编译(见下文),新配置才会生效。
由于部分原因,目前同一个编译单元中,两个仅调用相似simt rma接口的vf函数会导致编译错误(尽管编译不会报错,运行时会有错误),本样例通过修改源码以测试不同的simt RMA接口,并提供了常量定义以方便修改。
支持的设备
- Ascend950
使用方式
-
配置 CANN 环境变量 编译前需先加载 CANN 的环境变量(按实际安装路径选择其一):
# 默认安装路径 source /usr/local/Ascend/cann/bin/set_env.sh # 自定义安装路径 source ${install_path}/cann/bin/set_env.sh -
编译项目 在
shmem/根目录下执行编译脚本:bash scripts/build.sh -examples -enable_simt -soc_type Ascend950 -
运行示例程序 进入示例目录并执行运行脚本:
cd examples/simt_rma_perftest bash run.sh [options]
脚本参数说明
run.sh 支持以下参数,用于调节测试规模与条件:
| 参数 | 说明 | 默认值 |
|---|---|---|
--used_core |
每个 PE 使用的 Core(Block)数量。 | 32 |
--warmup_loops |
正式测试前的预热循环次数,用于消除冷启动影响。 | 50 |
--loops |
正式采样的循环次数。 | 1000 |
--bytes_in_exp_min |
单次传输数据量的下界,取值为 2 的指数(例如 10 表示 210=10242^{10} = 1024 字节)。 |
10 |
--bytes_in_exp_max |
单次传输数据量的上界,取值为 2 的指数。 | 14 |
--ub_size |
每个 Core 使用的 Unified Buffer 大小,单位 KB。仅在 SIMD 模式下生效;默认的 SIMT 模式不使用该参数。 | 16 |
本测试为固定的两卡(Active PE0 / Passive PE1)模型,启动进程数与程序内 PE 数均固定为 2,
run.sh不提供调节卡数的参数。
测试会从
bytes_in_exp_min到bytes_in_exp_max逐个指数遍历单次传输数据量(即 2min,2min+1,…,2max2^{min}, 2^{min+1}, \dots, 2^{max} 字节),每个数据量各产出一行统计结果。
例如,测试 4 个 Core 在传输 282^8 到 2122^{12} 字节数据时的性能表现:
bash run.sh --used_core 4 --bytes_in_exp_min 8 --bytes_in_exp_max 12
性能输出说明
测试正常结束后,Active PE(PE 0)会在示例目录下的 output/ 子目录中输出一个 .csv 性能统计文件,文件名格式为:
[DATA_SIZE]_[USED_CORE]_[OpType]_[VfType]_[minExp]-[maxExp]_w[warmup_loops]l[loops]_t[THREAD_COUNT]_.csv
.csv 文件中各列含义如下:
| 列名 | 说明 |
|---|---|
DataSize/B |
单次 RMA 通信传输的数据量(字节),对应本行采样的 2exp2^{exp} 取值。 |
Npus |
参与测试的 PE 数量,两卡测试下为 2。 |
Blocks |
参与通信的 Core(Block)数量,即 --used_core。 |
UBsize/KB |
每个 Core 使用的 Unified Buffer 大小(KB),即 --ub_size。 |
Bandwidth/GB/s |
本组参数测得的跨卡平均传输带宽。 |
CoreMaxTime/us |
多轮采样中,单个 Core 单次操作耗时最长的一轮时延(微秒)。 |
SingleCoreTime/us |
单个 Core 单次操作的平均时延(微秒),由总时长除以 loops 得到。 |