正如我们所知道的: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不兼容,因此必须禁用IOMMU才能使GPUDirect的RDMA工作。
如果我们将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;
}
我们在Windows7x64中获得了相等的指针,这意味着
cudaHostGetDevicePointer()
无效:
“充分的机制用于驱动程序之间交换MMIO区域”是什么意思?这里指的是什么机制?为什么我不能使用IOMMU通过虚拟地址访问通过PCIe到BAR的物理区域 - 另一个内存映射设备?host_src_ptr = 68719476736
uva_src_ptr = 68719476736
这是否意味着RDMA GPUDirect始终仅操作物理地址(在CPU的物理地址空间中),但我们发送给内核函数
uva_src_ptr
,它等于host_src_ptr
- CPU的虚拟地址空间中的简单指针?
nvidia_p2p_get_pages()
获取page_table
/SGL(scatter-gather-list)/SGE(scatter/gather entries),然后将它们提供给Infinibandibv_post_send()
,并将数据发送到远程CPU-RAM? - Alex