我们知道: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
从 PCI 设备的角度来看,GPUDirect 的 RDMA 目前依赖于所有物理地址相同。这使得它与 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 虚拟地址空间中的简单指针?