适用方向:高速数据采集、GPU 实时信号处理、5G/6G 基带处理、SDR,以及 HIL 硬件在环测试。

整体硬件架构

安装开发环境
在 PXI 端安装 NI-RDMA,下载地址:https://www.ni.com/en/support/downloads/drivers/download.ni-rdma.html
在 NVIDIA GPU 服务器上安装 RDMA 工具。以下命令均针对 Ubuntu Linux,并假设 NVIDIA 驱动及 CUDA 已安装完成。
首先,检查 GPU 状态:
bash
nvidia-smi
nvcc --version
安装网络诊断工具、RDMA 用户态库及编译依赖:
bash
sudo apt update
sudo apt install -y \
rdma-core \
ibverbs-utils \
infiniband-diags \
perftest \
libibverbs-dev \
librdmacm-dev \
libibumad-dev \
build-essential \
git \
autoconf \
automake \
libtool \
pkg-config \
ethtool \
pciutils
如果使用 GH200 或 DGX Spark 上已配置好的 NVIDIA DOCA-OFED,应优先复用现有驱动栈,避免直接覆盖 Aerial 已验证的内核驱动组合。
检查 RDMA 设备:
bash
rdma link show
ibv_devices
ibv_devinfo
lspci | grep -Ei "Mellanox|NVIDIA|Ethernet"
典型的设备可能显示为:
bash
device node GUID
mlx5_0 ...
mlx5_1 ...
mlx5_0、mlx5_1 是示例名称,实际名称以本机输出为准。
检查 GPU 与 ConnectX 的 PCIe 拓扑:
bash
nvidia-smi topo -m
lspci -tv
对于 x86 PCIe GPU,优先让 ConnectX 与 GPU 位于同一 PCIe Root Complex,最好经过尽量少的 PCIe Switch。
需要注意,PXIe-8280 与 GPU 服务器是两台计算机时,PXIe-8280 不需要与服务器 GPU 共用 PCIe Root Complex。这个要求针对服务器本地的 ConnectX 与 GPU 之间的 peer-to-peer DMA 路径。
PXI 端规划为:
bash
PXIe-8280: 192.168.100.1
ConnectX: 192.168.100.2
Netmask: 255.255.255.0
CUDA GPU 数据处理开发
创建 iq_power.cu:
bash
#include <cuda_runtime.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define CHECK(call) do { \
cudaError_t e = (call); \
if (e != cudaSuccess) { \
fprintf(stderr, "%s\n", \
cudaGetErrorString(e)); \
exit(EXIT_FAILURE); \
} \
} while (0)
// 每个 IQ 样本包含 I/Q 两个 int16_t
__global__ void iq_power(
const int16_t* iq,
float* power,
int n
) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) {
float i = (float)iq[2 * idx];
float q = (float)iq[2 * idx + 1];
power[idx] = i * i + q * q;
}
}
int main() {
const int N = 1024 * 1024;
const size_t input_bytes = N * 2 * sizeof(int16_t);
const size_t output_bytes = N * sizeof(float);
int16_t *h_iq = NULL;
int16_t *d_iq = NULL;
float *d_power = NULL;
CHECK(cudaMallocHost((void**)&h_iq, input_bytes));
for (int i = 0; i < N; i++) {
h_iq[2*i] = 100;
h_iq[2*i+1] = 200;
}
CHECK(cudaMalloc((void**)&d_iq, input_bytes));
CHECK(cudaMalloc((void**)&d_power, output_bytes));
// 阶段一:CPU Host Buffer -> GPU
CHECK(cudaMemcpy(d_iq, h_iq,
input_bytes, cudaMemcpyHostToDevice));
int threads = 256;
int blocks = (N + threads - 1) / threads;
iq_power<<<blocks, threads>>>(d_iq, d_power, N);
CHECK(cudaGetLastError());
CHECK(cudaDeviceSynchronize());
float result;
CHECK(cudaMemcpy(&result, d_power,
sizeof(float), cudaMemcpyDeviceToHost));
printf("Power[0] = %.1f\n", result);
CHECK(cudaFree(d_power));
CHECK(cudaFree(d_iq));
CHECK(cudaFreeHost(h_iq));
return 0;
}
编译:
bash
nvcc -O3 iq_power.cu -o iq_power
运行:
bash
./iq_power
