【发布时间】:2013-11-19 10:41:04
【问题描述】:
据我们所知:http://en.wikipedia.org/wiki/IOMMU#Advantages
IOMMU 可以支持外设内存分页。外围设备 使用 PCI-SIG PCIe 地址转换服务 (ATS) 页面请求 接口 (PRI) 扩展可以检测并发出对内存的需求 经理服务。
但是当我们使用 CUDA >= 5.0 的 nVidia GPU 时,我们可以使用 RDMA GPUDirect,并且知道:
http://docs.nvidia.com/cuda/gpudirect-rdma/index.html#how-gpudirect-rdma-works
传统上,像 BAR 窗口这样的资源被映射到用户或内核 使用 CPU 的 MMU 作为内存映射 I/O (MMIO) 的地址空间 地址。但是,由于当前的操作系统没有 在驱动程序之间交换 MMIO 区域的足够机制, NVIDIA 内核驱动程序导出函数以执行必要的 地址转换和映射。
http://docs.nvidia.com/cuda/gpudirect-rdma/index.html#supported-systems
GPUDirect 的 RDMA 目前依赖于所有物理地址 从 PCI 设备的角度来看是相同的。这使它 与 IOMMU 不兼容,因此必须为 RDMA 禁用它们 GPUDirect 工作。
如果我们将 CPU-RAM 分配并映射到 UVA,如下所示:
#include <iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
int main() {
// Can Host map memory
cudaSetDeviceFlags(cudaDeviceMapHost);
// Allocate memory
unsigned char *host_src_ptr = NULL;
cudaHostAlloc(&host_src_ptr, 1024*1024, cudaHostAllocMapped);
std::cout << "host_src_ptr = " << (size_t)host_src_ptr << std::endl;
// Get UVA-pointer
unsigned int *uva_src_ptr = NULL;
cudaHostGetDevicePointer(&uva_src_ptr, host_src_ptr, 0);
std::cout << "uva_src_ptr = " << (size_t)uva_src_ptr << std::endl;
int b; std::cin >> b;
return 0;
}
我们在 Windwos7x64 中得到相等的指针,这意味着 cudaHostGetDevicePointer() 什么都不做:
host_src_ptr = 68719476736
uva_src_ptr = 68719476736
“驱动程序之间交换 MMIO 区域的充分机制”是什么意思,这里的机制是什么意思,以及为什么我不能通过使用虚拟地址通过 PCIe 访问 BAR 的物理区域来使用 IOMMU - 另一个内存映射通过 PCIe 的设备?
这是否意味着 RDMA GPUDirect 总是只操作物理地址(在 CPU 的物理地址空间中),但是为什么我们发送到内核函数 uva_src_ptr 等于 host_src_ptr - CPU 中的简单指针虚拟地址空间?
【问题讨论】:
标签: cuda gpgpu pci-e memory-mapping gpudirect