You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

2024年Windows平台C++开发InfiniBand RDMA的最小环境配置需求

Windows环境下基于InfiniBand实现跨机RDMA的最小C++示例配置方案

一、驱动与SDK准备

  • 驱动:安装NVIDIA Mellanox ConnectX 4+ Windows驱动(2024年仍提供兼容版本),安装时必须勾选「Network Direct SPI」组件,确保网卡能被Network Direct接口识别。
  • SDK:安装NVIDIA Mellanox Windows SDK,SDK中包含Network Direct的头文件(ndspi.h)、静态库(nd.lib)及相关文档,默认安装路径为C:\Program Files\Mellanox\MLNX_WinOF2\SDK。

二、依赖库与项目配置

  • 核心依赖库:nd.lib(Network Direct SPI核心库)、ws2_32.lib(Windows TCP/IP辅助库,用于交换RDMA队列对信息)。
  • VS项目配置:
    1. 将SDK的include路径(如C:\Program Files\Mellanox\MLNX_WinOF2\SDK\include)添加到项目「附加包含目录」。
    2. 将SDK的lib路径(如C:\Program Files\Mellanox\MLNX_WinOF2\SDK\lib\x64)添加到项目「附加库目录」。
    3. 在「附加依赖项」中加入nd.lib;ws2_32.lib。

三、最小C++示例核心逻辑

通用初始化与清理

#include <windows.h>
#include <ndspi.h>
#include <winsock2.h>
#include <iostream>

// 初始化Network Direct环境
ND_STATUS InitND() {
    ND_STATUS status = NdStartup();
    if (status != ND_SUCCESS) {
        std::cerr << "NdStartup failed: " << status << std::endl;
        return status;
    }
    return ND_SUCCESS;
}

// 清理Network Direct环境
void CleanupND() {
    NdShutdown();
}

服务端核心代码(简化版)

int ServerMain() {
    if (InitND() != ND_SUCCESS) return 1;

    // 获取本地RDMA适配器信息
    ND_ADAPTER_INFO adapterInfo;
    ND_STATUS status = NdGetAdapterInfo(0, &adapterInfo, sizeof(adapterInfo));
    if (status != ND_SUCCESS) {
        std::cerr << "NdGetAdapterInfo failed" << std::endl;
        CleanupND();
        return 1;
    }

    // 创建保护域(PD)
    ND_PROTECTION_DOMAIN_HANDLE pd;
    status = NdCreateProtectionDomain(adapterInfo.AdapterHandle, NULL, &pd);
    if (status != ND_SUCCESS) {
        std::cerr << "NdCreateProtectionDomain failed" << std::endl;
        NdClose(adapterInfo.AdapterHandle);
        CleanupND();
        return 1;
    }

    // 创建队列对(QP)、内存区域(MR)等资源(省略参数细节,需匹配客户端配置)
    ND_QUEUE_PAIR_HANDLE qpHandle;
    // ... 此处补充创建QP、MR的代码

    // 用TCP交换QP地址信息(省略TCP服务端监听、连接逻辑)
    // 发送本地QP地址到客户端,接收客户端QP地址

    // 建立QP连接并发送数据
    ND_CONNECT_PARAMS connectParams = {0};
    // 填充remoteQpAddress等参数
    status = NdConnect(pd, qpHandle, &connectParams, NULL);
    if (status == ND_SUCCESS) {
        char sendBuf[] = "RDMA Cross-Machine Test";
        NdSend(pd, qpHandle, sendBuf, sizeof(sendBuf), NULL, 0, NULL);
    }

    // 清理资源
    NdClose(qpHandle);
    NdClose(pd);
    NdClose(adapterInfo.AdapterHandle);
    CleanupND();
    return 0;
}

客户端核心代码(简化版)

int ClientMain() {
    if (InitND() != ND_SUCCESS) return 1;

    // 获取本地RDMA适配器信息
    ND_ADAPTER_INFO adapterInfo;
    ND_STATUS status = NdGetAdapterInfo(0, &adapterInfo, sizeof(adapterInfo));
    if (status != ND_SUCCESS) {
        std::cerr << "NdGetAdapterInfo failed" << std::endl;
        CleanupND();
        return 1;
    }

    // 创建保护域(PD)
    ND_PROTECTION_DOMAIN_HANDLE pd;
    status = NdCreateProtectionDomain(adapterInfo.AdapterHandle, NULL, &pd);
    if (status != ND_SUCCESS) {
        std::cerr << "NdCreateProtectionDomain failed" << std::endl;
        NdClose(adapterInfo.AdapterHandle);
        CleanupND();
        return 1;
    }

    // 创建队列对(QP)、内存区域(MR)等资源(省略参数细节,需匹配服务端配置)
    ND_QUEUE_PAIR_HANDLE qpHandle;
    // ... 此处补充创建QP、MR的代码

    // 用TCP连接服务端,交换QP地址信息(省略TCP客户端连接逻辑)
    // 接收服务端QP地址,发送本地QP地址

    // 等待接收数据
    char recvBuf[1024] = {0};
    NdReceive(pd, qpHandle, recvBuf, sizeof(recvBuf), NULL, 0, NULL);
    std::cout << "Received data: " << recvBuf << std::endl;

    // 清理资源
    NdClose(qpHandle);
    NdClose(pd);
    NdClose(adapterInfo.AdapterHandle);
    CleanupND();
    return 0;
}

四、关键注意事项

  • 两台机器需处于同一InfiniBand网络,网卡已完成基础配置(如IPoIB或专用RDMA网络)。
  • 防火墙需允许TCP辅助通信的自定义端口(如示例中使用的5555端口)。
  • 内存区域(MR)需使用RDMA可访问内存,推荐用NdAllocateMemory分配,或通过VirtualLock锁定用户态内存。

内容的提问来源于stack exchange,提问作者Tom McLean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:10:55