1. 为什么要在 softroce 上折腾带宽和延迟
softroce(Soft-RDMA over Ethernet)是把 RDMA 的 verbs 语义用软件实现在普通以太网卡上的一套方案,内核里对应的模块叫rdma_rxe。它最大的价值是:你不需要买昂贵的 RoCE 网卡,用两台普通机器加一块普通网卡,就能把 RDMA 的编程接口、队列对(QP)、完成队列(CQ)这套东西跑起来。对于要验证分布式存储、MPI 集合通信、或者自己写 verbs 程序的开发者来说,softroce 是一个成本极低的实验床。
但问题也很直接:软件实现意味着 CPU 要参与大量数据搬运,带宽和延迟跟硬件 RoCE 差一个数量级。所以真正要做的不是"能不能通",而是"通了多少、延迟多少、瓶颈在哪"。这就必须有一套可复制的配置骨架,加上标准的perftest测试命令,再配合一个稳定的模型/API 通道来辅助你查文档、生成脚本、解读结果。
这篇就按这个思路走:先把 softroce 两端配好,用ib_send_bw和ib_send_lat跑出带宽和延迟数字,再讲怎么判读结果、怎么排掉最常见的坑。中间涉及查参数、生成测试脚本、对比不同 MTU 下的表现时,我会用 TaoToken 的统一 Key 走 API 通道,把模型对话和编码辅助串起来,省得在多个平台之间来回切。
适合谁看:手里有两台 Linux 机器(物理机或虚拟机都行)、想快速搭一个 RDMA 软实现验证环境、并且需要拿到可对比的带宽/延迟基线的开发者。下面所有命令都可以直接复制。
2. TaoToken 前置:统一 Key 与 API 通道准备
在开始配 softroce 之前,先把辅助通道准备好。原因很实际:softroce 的调参涉及大量内核模块参数、perftest选项、MTU 与 GID 索引的对应关系,靠记忆很容易出错。用 TaoToken 的统一 Key,可以在一个入口下调用不同模型来做三件事——查ib_send_bw参数含义、生成两端对齐的测试脚本、把测试输出的原始数字翻译成结论。
TaoToken 的定位是统一模型接入层,官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api 。它的好处是 Key 统一,不用为每个模型单独申请和记额度,对于"边配环境边查资料"这种碎片化场景比较顺手。
具体操作分两步。第一步,进控制台创建 API Key:
- 控制台地址:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- API Keys 管理页:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
创建后拿到形如sk-xxxx的 Key,先存到环境变量里,后面所有请求都复用它:
export TAOTOKEN_API_KEY="sk-你的key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"第二步,验证通道是否可用。用一条最小的对话请求确认 Key 生效,避免后面调模型时才发现鉴权失败:
curl -s "$TAOTOKEN_BASE_URL/v1/chat/completions" \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "用一句话说明 ib_send_bw 的 -F 参数作用"}], "max_tokens": 200 }'返回里能看到choices[0].message.content就说明通道正常。如果你更习惯在网页里直接问,模型对话入口是 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,效果一样,只是不用自己拼 curl。
注意:Key 只放在环境变量或本地配置里,不要写进会提交到仓库的脚本。测试脚本里用
$TAOTOKEN_API_KEY引用即可。
如果你后面要长期跑编码辅助、批量生成测试脚本,可以看下 Coding Plan 的额度方式:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。接入细节和参数说明统一在文档里:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
3. softroce 可复制配置骨架
这一节是全文的技术核心。目标是把两台机器(下面叫 server 和 client)都配成能用rxe设备跑 verbs 的状态。假设两块网卡分别是ens1f0(server)和ens1f1(client),实际替换成你自己的接口名。
3.1 安装依赖与加载内核模块
两台机器都要做。perftest提供ib_send_bw、ib_send_lat等工具,rdma-core提供用户态库:
# Ubuntu / Debian sudo apt update sudo apt install -y rdma-core perftest iproute2 # RHEL / CentOS / Rocky sudo dnf install -y rdma-core perftest iproute加载 softroce 内核模块并确认设备出现:
sudo modprobe rdma_rxe sudo rdma link add rxe0 type rxe netdev ens1f0 rdma link show正常输出类似:
link rxe0/1 state ACTIVE physical_state LINK_UP netdev ens1f0看到state ACTIVE和LINK_UP才算成功。如果rdma link add报Operation not supported,多半是内核没编rdma_rxe,用modinfo rdma_rxe确认一下。
3.2 关键参数:MTU 与 GID 索引
softroce 的性能对 MTU 非常敏感。默认 1500 时带宽会被小包拖死,建议两端网卡都调到 9000(前提是链路中间设备也支持,直连或同一交换机下一般没问题):
sudo ip link set ens1f0 mtu 9000 ip link show ens1f0 | grep mtuGID 索引决定走 IPv4 还是 IPv6 映射。softroce 下通常-i 1对应 RoCEv2 的 IPv4 GID。用下面命令确认:
show_gids输出里找到rxe0那一行,记下v2且是 IPv4 对应的索引号,后面-i参数就填它。多数环境是 1,但不要想当然,以show_gids为准。
3.3 用 TaoToken 生成两端对齐的测试脚本
手工敲两端命令容易把参数写歪。我一般让模型按固定模板生成一份脚本,保证 server 和 client 的-d、-i、-n、-F完全一致。请求示例:
curl -s "$TAOTOKEN_BASE_URL/v1/chat/completions" \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "生成 softroce 带宽和延迟测试脚本,设备 rxe0,GID 索引 1,消息数 10000,输出用 Gb/s,server 和 client 参数必须一致,client 需要传 server_ip 参数"}], "max_tokens": 800 }'拿到脚本后自己核对一遍参数再执行。核心命令其实就是下面这几条,可以直接用。
4. 验证请求与成功结果判读
4.1 带宽测试:ib_send_bw
server 端先起监听:
ib_send_bw -n 10000 -d rxe0 -i 1 -F --report_gbitsclient 端连过去:
ib_send_bw -n 10000 -d rxe0 -i 1 -F --report_gbits <server_ip>参数含义:-n 10000是消息数,-d rxe0指定设备,-i 1是 GID 索引,-F允许在无 CPU 亲和性限制下运行,--report_gbits让结果以 Gb/s 输出而不是 MB/s。
成功时 client 端会打印类似:
--------------------------------------------------------------------------------------- #bytes #iterations BW peak[Gb/sec] BW average[Gb/sec] MsgRate[Mpps] 65536 10000 9.87 9.72 0.018535 ---------------------------------------------------------------------------------------BW average就是你要的带宽数字。softroce 在 9000 MTU、单 QP 下,普通千兆网卡大概 0.9 Gb/s 左右,万兆网卡能到 6–9 Gb/s,具体取决于 CPU 主频和内存带宽。如果只有几百 Mb/s,先查 MTU 是不是没生效。
4.2 延迟测试:ib_send_lat
server:
ib_send_lat -n 10000 -d rxe0 -i 1 -F --report_gbitsclient:
ib_send_lat -n 10000 -d rxe0 -i 1 -F --report_gbits <server_ip>成功输出:
#bytes #iterations t_min[usec] t_max[usec] t_typical[usec] 2 10000 18.42 95.31 19.87t_typical是典型往返延迟。softroce 因为是软件路径,单次往返通常在 15–40 微秒,比硬件 RoCE 的 1–2 微秒高一个量级,这是正常的,不要拿硬件指标来对标。
4.3 结果判读的三个要点
第一,看BW average是否随 MTU 变化。把两端 MTU 从 1500 改到 9000 再跑一次,带宽应该有明显提升,否则说明 MTU 没真正生效或链路中间有设备降了 MTU。
第二,看延迟的t_max和t_typical差距。如果t_max是t_typical的十几倍,说明有抖动,可能是 CPU 被其他进程抢占,用taskset把测试进程绑到固定核上再测。
第三,多 QP 对比。加-q 4跑多队列,观察带宽是否线性增长。softroce 下多 QP 能提升吞吐,但受限于单核软中断处理能力,增长往往不是线性的,这个拐点就是你的环境瓶颈。
5. 本篇常见错排查
5.1 rdma link add 失败
报Operation not supported或No such device。先modinfo rdma_rxe确认模块存在,再确认网卡名拼写正确(用ip link看)。如果网卡是虚拟接口(比如某些容器 veth),softroce 可能不支持,换成物理网卡或 macvlan。
5.2 ib_send_bw 卡在 "Waiting for client"
server 起来了但 client 连不上。九成是防火墙挡了 RDMA CM 的端口,或者server_ip填错。先ping通,再确认两端rdma link show都是 ACTIVE。softroce 走的是 UDP 4791 端口,检查一下:
sudo ss -ulnp | grep 47915.3 带宽只有几百 Mb/s
最常见原因是 MTU 没生效。用ip link show <iface> | grep mtu在两端都确认是 9000。另一个原因是 GID 索引选错,走了 IPv6 路径导致额外开销,用show_gids重新核对-i的值。
5.4 延迟忽高忽低
CPU 频率调节和中断亲和性都会影响。测试前把 CPU governor 设成 performance:
sudo cpupower frequency-set -g performance再用taskset -c 2 ib_send_lat ...把进程绑到固定核,抖动会明显下降。
5.5 用 TaoToken 辅助排障
遇到不认识的报错,把原始输出贴给模型,让它给出排查顺序,比自己在文档里翻快很多。请求时把rdma link show、show_gids、ib_send_bw的完整输出一起带上,模型能直接定位到是 GID 问题还是 MTU 问题。通道还是用前面那个统一 Key,模型对话入口 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 直接可用。
6. 把配置和验证串成闭环
整套流程走下来,你手里应该有两组数字:一组是ib_send_bw的BW average,一组是ib_send_lat的t_typical。这两个数字就是你后续所有优化的基线。改一个参数(MTU、QP 数、CPU 绑定)就重跑一次,对比基线,才知道改动有没有用。
如果后面要把这套环境接到自动化测试里,或者用模型批量生成不同参数组合的测试脚本,走 API 通道会更顺:接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。长期做编码和 Agent 辅助的话,Coding Plan 的额度方式可以看 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
最后留一个实操建议:softroce 的瓶颈几乎总在 CPU 软中断上,与其反复调perftest参数,不如先用mpstat -P ALL 1看一眼测试时哪个核跑满了,把那个核上的其他负载挪走,带宽往往立刻上一个台阶。这比换任何参数都直接。