go_rdmanet_bw 详解
go_rdmanet_bw 不只是「高层带宽工具」——它内置了三种发送方式,正好对应
rdmanet 从易用到极致吞吐的不同档位。理解这三种模式,也就理解了高层 API 的性能边界在哪。
三种模式速查
| 模式 | 开关 | 用的 API | 典型吞吐(64KB) |
|---|---|---|---|
| 逐条发送 | 默认 | Conn.SendMsg | ~18 Gb/s |
| 批量消息 | -b N | Conn.SendBatch | ~28 Gb/s |
| RawConn | --raw | RawConn.PipelineBatch | ~210 Gb/s |
(吞吐为某台 400G RoCE v2 主机上的实测量级,仅供横向对比,会随硬件/配置变化。)
--raw 现在输出
MiB/s(2²⁰,与 ib_send_bw 同口径,可直接比);Go 版 go_send_bw 输出
MB/s(10⁶ byte/s,×8÷1000 得 Gb/s);C 版 ib_send_bw 输出 MiB/s
(2²⁰ byte/s,×2²⁰×8÷10⁹ 得 Gb/s)。同机 64KB 多次实测峰值换算后约为:ib_send_bw
~392 Gb/s、go_send_bw ~392 Gb/s(可追平 C)、RawConn ~232 Gb/s。
注意这台共享 GPU 机抖动很大(±25%),单次数字不可比,详见
CGO 开销与原生 RDMA 的差距。
模式一:默认逐条 SendMsg
不带任何开关时,客户端逐条 SendMsg。这是延迟受限的——同一时刻只有一条消息 in-flight,
吞吐 ≈ 1/单条往返延迟,远喂不满网卡。它演示的是 Conn 最朴素的用法,不是性能档。
./bin/go_rdmanet_bw -d mlx5_1 -x 3 # 服务端
./bin/go_rdmanet_bw -s 65536 -n 1000000 -d mlx5_1 -x 3 33.0.226.25:18515
模式二:--batch 批量消息
加 -b N(即 --batch)后,客户端改用 SendBatch、服务端用 RecvBatch,
摊薄每次调用的固定开销。注意:Conn 仍带封帧、信用流控、bounce 拷贝,所以即便批量,
吞吐提升也有限——这恰恰是 RawConn 存在的理由。
./bin/go_rdmanet_bw -d mlx5_1 -x 3 -b 32 # 服务端(两端 -b 不必一致,但都要够大)
./bin/go_rdmanet_bw -s 65536 -n 1000000 -d mlx5_1 -x 3 -b 32 33.0.226.25:18515
输出带模式标签,例如 SendBatch(32): sent ... Gb/s, ... Mpps。
服务端无需 -n——收到客户端关闭(io.EOF)即结束。
模式三:--raw 极限吞吐
加 --raw 切到 RawConn:无封帧、无流控、单 goroutine post+busy-poll,
吞吐量级接近底层 perftest(峰值约为 go_send_bw 的 0.6 倍,但实测两者差距随机器状态在
1.05×~1.76× 间波动、某些轮次几乎持平;差距落在完成到达(poll)而非 cgo 提交,详见
CGO 开销与原生 RDMA 的差距,用 GORDMA_PROBE=1 可量化)。
此模式下 -b 的含义变为 tx-depth(in-flight WR 数)。
./bin/go_rdmanet_bw --raw -d mlx5_1 -x 3 -b 128 # 服务端
./bin/go_rdmanet_bw --raw -s 65536 -n 1000000 -d mlx5_1 -x 3 -b 128 33.0.226.25:18515
输出为 ib_send_bw 风格的表格(BW average[MiB/sec] + MsgRate[Mpps]),可与
ib_send_bw 直接并排比较。RawConn 恒用 TCP 握手 + 忙轮询,所以
--poll/--handshake 在此模式被忽略。
--raw -s 1024 -n 5000000 -b 128 的 Mpps 会比大包高一个数量级。
对齐 perftest:诊断开关
想搞清「RawConn 为什么比 go_send_bw 慢」,把 RawConn 的跑法逐项对齐到 perftest 基线,再看差距落在哪:
| 开关 | 作用 |
|---|---|
--raw-onebuf | 收发两端都复用单块固定区域(而非轮转 tx-depth 个槽位),对齐 perftest 的热工作集。两端都要加。 |
--raw-single | 客户端逐条 PostSend(Pipeline)而非批量提交(PipelineBatch),对齐 go_send_bw。 |
GORDMA_PROBE=1 | 环境变量,打开后客户端额外打印 post(提交 WR 耗时占比)vs poll(忙等完成耗时占比)。poll 占比高=瓶颈在网卡/对端;post 占比高=瓶颈在提交路径(cgo)。 |
# 完全对齐 go_send_bw,并打开探针看时间花在哪
GORDMA_PROBE=1 ./bin/go_rdmanet_bw --raw --raw-onebuf -d mlx5_1 -x 3 -b 128 # 服务端
GORDMA_PROBE=1 ./bin/go_rdmanet_bw --raw --raw-onebuf --raw-single -s 65536 -n 1000000 -d mlx5_1 -x 3 -b 128 33.0.226.25:18515
其它实用开关
| 开关 | 作用 |
|---|---|
--depth N | 队列深度 / 信用窗口(两端一致才有对照意义;0=库默认 128) |
--poll busy|event | 非 raw 模式的 CQ 排空方式:忙轮询低延迟、事件驱动省 CPU |
--handshake | 非 raw 模式改用 TCP 握手而非 rdma_cm |
怎么选模式
- 想看「最朴素的
Conn能跑多少」→ 默认模式。 - 想看「批量摊薄开销的效果」→
-b N。 - 想看「
rdmanet能逼近多少网卡线速」→--raw,再配大-b(tx-depth)。 - 想要绝对基准 → 直接跑底层
go_send_bw对照。