【发布时间】:2013-10-31 20:16:13
【问题描述】:
我正在尝试直接从 Linux 中的另一个 PCIe 设备访问 NIC 中的 DMA 地址。具体来说,我正在尝试从 NVIDIA GPU 读取它以绕过 CPU。我研究了零拷贝网络和 DMA 到用户空间的帖子,但他们要么没有回答问题,要么涉及从内核空间到用户空间的一些拷贝。由于延迟不一致,我试图避免使用任何 CPU 时钟,并且我有非常严格的延迟要求。
我获得了我使用的 intel 卡的 NIC 驱动程序(e1000e 驱动程序),我找到了分配环形缓冲区的位置。正如我从之前阅读的一篇论文中了解到的那样,我会对 dma_addr_t 类型的描述符感兴趣。它们还有一个名为 dma 的 rx_ring 结构成员。我使用 ioctl 调用同时传递了 desc 和 dma 成员,但除了零之外,我无法在 GPU 中获得任何东西。
GPU代码如下:
int *setup_gpu_dma(u64 addr)
{
// Allocate GPU memory
int *gpu_ptr;
cudaMalloc((void **) &gpu_ptr, MEM_SIZE);
// Allocate memory in user space to read the stuff back
int *h_data;
cudaMallocHost((void **)&h_data, MEM_SIZE);
// Present FPGA memory to CUDA as CPU locked pages
int error = cudaHostRegister((void **) &addr, MEM_SIZE,
CU_MEMHOSTALLOC_DEVICEMAP);
cout << "Allocation error = " << error << endl;
// DMA from GPU memory to FPGA memory
cudaMemcpy((void **) &gpu_ptr, (void **)&addr, MEM_SIZE, cudaMemcpyHostToDevice);
cudaMemcpy((void **) &h_data, (void **)&gpu_ptr, MEM_SIZE, cudaMemcpyDeviceToHost);
// Print the data
// Clean up
}
我做错了什么?
【问题讨论】:
-
在 cmets 中说“FPGA”的地方,应该说“NIC 缓冲区”吗?
-
是的,应该。我从另一个例子中复制了这段代码的一部分,在 Windows 中做了非常相似的事情。他们正在从 FPGA PCI-e 板上读取数据。对此感到抱歉。
-
您有没有机会查看 NVIDIA 的 GPUDirect 文档:docs.nvidia.com/cuda/gpudirect-rdma/index.html
-
是的,我有,但是有几个问题。首先,这不适用于 Geforce GPU。与其将 GPU 地址提供给 NIC,不如将 NIC 地址提供给 GPU。其次,NIC 驱动程序使用环形缓冲区,据我了解,这使得它很难与 GPU 内存一起使用。