3、性能基准测试工具:perftest工具集

聊到IB网络的性能测试,perftest工具集是绕不开的。我入行那会儿,第一次接触IB网络,就被同事扔过来一个perftest的编译命令。说实话,当时看着那一堆ib_send_bw、ib_write_lat之类的名字,心里是有点懵的。但用顺手之后你会发现,这套工具就是IB网络的「听诊器」——哪里堵、哪里慢,一测便知。

3.1 perftest工具集概览

perftest是Mellanox(现NVIDIA)官方维护的一套开源基准测试工具。它直接调用InfiniBand的Verbs API,绕过了内核协议栈。说白了,就是让数据在用户态和网卡之间直来直去,测出来的才是IB网络的真实性能。

这套工具的核心测试模式分三种:

  • Send/Recv:传统的双端收发,需要接收端提前注册缓冲区
  • Write:RDMA写操作,一端直接写另一端的内存
  • Read:RDMA读操作,一端从另一端的内存拉数据

每种模式又分带宽测试(bw)和延迟测试(lat)。所以你会看到6个常用命令:ib_send_bw、ib_send_lat、ib_write_bw、ib_write_lat、ib_read_bw、ib_read_lat。

核心要点:perftest测的是「裸性能」,不经过任何中间件。你测出来的数字,就是这张网卡和这条链路能跑到的天花板。

3.2 ib_send_bw / ib_send_lat

这两个命令测的是最基础的Send/Recv模式。我习惯先跑ib_send_bw,看看链路带宽能不能达标。

用法很简单,分服务端和客户端:

# 服务端(被动端)
ib_send_bw -d mlx5_0 -p 18515

# 客户端(主动端)
ib_send_bw -d mlx5_0 -p 18515 192.168.1.100

这里-d指定设备,-p指定端口号。客户端后面跟服务端的IP地址。

跑完之后你会看到类似这样的输出:

---------------------------------------------------------------------------------------
                    RDMA_CM BW Test
 Dual-port       : OFF          Device         : mlx5_0
 Number of qps   : 1            Transport type : IB
 Connection type : RC           Using SRQ      : OFF
---------------------------------------------------------------------------------------
  local address: LID 0x2 QPN 0x8000 RKEY 0x100 PSN 0x1234
  remote address: LID 0x3 QPN 0x8001 RKEY 0x200 PSN 0x5678
---------------------------------------------------------------------------------------
  #bytes     #iterations    BW peak[MB/sec]    BW average[MB/sec]   MsgRate[Mpps]
  65536      1000           11264.0            11250.3              0.172
---------------------------------------------------------------------------------------

注意看BW average那一列。如果是100Gbps的IB网络,单流理论上限大概在11700 MB/s左右。我遇到过好几次,测出来只有8000多,排查下来发现是PCIe链路降速了——你想想看,网卡插在x8的槽上,带宽直接砍半。

ib_send_lat测的是延迟,用法类似:

# 服务端
ib_send_lat -d mlx5_0 -p 18515

# 客户端
ib_send_lat -d mlx5_0 -p 18515 192.168.1.100

输出里有个关键指标叫「2微秒延迟」。对于现代IB网络,RC模式下的Send延迟通常在1.5微秒以内。如果超过2微秒,我建议你检查一下CPU频率是否稳定,或者有没有中断亲和性设置不当的问题。

个人经验:测延迟的时候,记得把消息大小设小一点,比如2字节。默认是65536字节,测出来的延迟会偏大。加个-s 2参数就行。

3.3 ib_write_bw / ib_write_lat

RDMA Write是实际生产中用得最多的操作。比如分布式存储里的数据复制,基本都是走Write。为什么?因为Write操作不需要接收端CPU参与,数据直接写到远端内存里。

用法和Send系列几乎一样:

# 服务端
ib_write_bw -d mlx5_0 -p 18515

# 客户端
ib_write_bw -d mlx5_0 -p 18515 192.168.1.100

这里有个坑,我曾经踩过。默认情况下,ib_write_bw用的是单QP(队列对)。对于大消息,单QP带宽可能跑不满。这时候加个--qp=4或者--qp=8,用多个QP并发,带宽能提升不少。

ib_write_lat测的是Write操作的延迟。注意,Write延迟通常比Send略高一点点,因为Write需要远端硬件完成数据写入后才返回确认。但差距很小,一般在0.1微秒以内。

操作类型典型延迟(4字节)典型带宽(1MB消息)
ib_send1.2 - 1.5 µs11.0 - 11.5 GB/s
ib_write1.3 - 1.6 µs11.2 - 11.7 GB/s
ib_read1.5 - 1.8 µs10.5 - 11.0 GB/s

嗯,这里要注意,上表的数据是基于100Gbps HDR网卡、PCIe 4.0 x16的典型环境。你的环境可能略有差异。

3.4 ib_read_bw / ib_read_lat

RDMA Read用得相对少一些,但在某些场景下不可或缺。比如分布式锁服务,需要从远端读取锁状态。Read操作的特点是:主动端发起请求,远端网卡把数据读出来发回来。整个过程远端CPU不感知。

用法依然很统一:

# 服务端
ib_read_bw -d mlx5_0 -p 18515

# 客户端
ib_read_bw -d mlx5_0 -p 18515 192.168.1.100

Read的带宽通常比Write低5%-10%。为什么?因为Read需要走一个「请求-响应」的往返。你想想看,Write是单向推数据,Read是拉数据,多了一个握手开销。

ib_read_lat测的是Read延迟。这个值一般比Write高0.2-0.3微秒。如果你的Read延迟异常高,比如超过2.5微秒,我建议你检查一下对端的内存注册情况。我曾经遇到过,对端注册的内存区域太小,导致频繁的page fault,延迟直接飙到5微秒。

避坑指南:我曾经在生产环境遇到过一个问题——ib_read_bw跑出来带宽只有Write的一半。排查了两天,最后发现是交换机的流控策略配置不对。Read操作对丢包特别敏感,一旦触发重传,性能断崖式下跌。所以,如果你发现Read性能异常,先查交换机。

3.5 知识体系总览

下面这张图是我自己整理的perftest工具集知识结构,帮你快速建立全局认知:

perftest 工具集知识体系 perftest 工具集 Send / Recv RDMA Write RDMA Read ib_send_bw ib_send_lat ib_write_bw ib_write_lat ib_read_bw ib_read_lat 关键参数 -d 设备 -p 端口 -s 消息大小 性能指标 带宽(MB/s) 延迟(µs) 消息速率 常见问题 PCIe降速 中断亲和性 流控 优化技巧 多QP并发 大页内存 CPU绑定 核心原则:先测带宽看上限,再测延迟看底线 测试环境:100Gbps HDR / PCIe 4.0 x16 / RC模式 建议:每次变更配置后,重新跑一轮全量测试

3.6 实用技巧汇总

最后,分享几个我这些年积累下来的小技巧:

  • 先跑单流,再跑多流:单流能看出链路本身的问题,多流能看出交换机和网卡的并发能力
  • 消息大小要覆盖全范围:从2字节到1MB,每个量级都跑一遍。小消息看延迟,大消息看带宽
  • 记录基线数据:每次硬件变更后,把测试结果保存下来。我习惯用日期+拓扑命名,比如「20250115_2节点_直连」
  • 注意CPU亲和性:perftest默认绑定当前CPU核心。如果你在NUMA架构上跑,记得用numactl把进程绑定到网卡所在的NUMA节点

个人习惯:我每次调优完,都会把6个命令串成一个脚本,一键跑完。输出结果重定向到文件,方便后续对比。脚本里加个时间戳,哪天出了性能问题,翻出来一看就知道是哪个版本开始变差的。

perftest工具集虽然看起来简单,但用好它需要你对IB网络的底层机制有一定理解。别急,多跑几次,多对比数据,慢慢你就能从数字里读出网络的状态了。


公众号:蓝海资料掘金营,微信deep3321