CUDA零拷贝内存注意事项

Der*_*rek 10 c++ cuda

我想弄清楚是否使用cudaHostAlloc(或cudaMallocHost?)是合适的.

我正在尝试运行一个内核,我的输入数据超过了GPU上可用的数量.

我可以将cudaMalloc占用比GPU更多的空间吗?如果没有,让我说我分配1/4我需要的空间(适合GPU),使用固定内存有什么好处吗?

我基本上必须从那个1/4大小的缓冲区复制到我的全尺寸malloc缓冲区,这可能不比仅使用正常的cudaMalloc快吗?

这种典型的使用场景是否适合使用cudaMallocHost:

  1. 分配固定主机内存(让我们称之为"h_p")
  2. 使用输入数据填充h_p-
  3. 在GPU上获取h_p的设备指针
  4. 使用该设备指针运行内核来修改数组的内容 -
  5. 使用正常的h_p,现在修改了内容 -

那么 - 第4步和第5步之间没有副本可以开心吗?

如果这是正确的,那么我可以看到至少适合GPU的内核的优势

Seb*_*ian 6

在涉及CUDA应用程序的性能时,内存传输是一个重要因素.cudaMallocHost可以做两件事:

  • 分配固定内存:这是CUDA运行时可以跟踪的页锁定主机内存.如果以这种方式分配的主机内存cudaMemcpy作为源或目标参与,则CUDA运行时将能够执行优化的内存传输.
  • 分配映射内存:这也是页面锁定内存,可以直接用于内核代码,因为它映射到CUDA地址空间.为此,您必须在使用任何其他CUDA函数之前设置cudaDeviceMapHost标志cudaSetDeviceFlags.GPU内存大小不限制映射主机内存的大小.

我不确定后一种技术的表现.它可以让你非常好地重叠计算和通信.

如果您在内核中的块中访问内存(即,您不需要整个数据,只需要一个部分),您可以使用多缓冲方法,利用异步内存传输,cudaMemcpyAsync在GPU上具有多个缓冲区:计算一个缓冲区,将一个缓冲区传输到主机,同时将一个缓冲区传输到设备.

我相信在使用cudaDeviceMapHost分配类型时,关于使用场景的断言是正确的.您不必进行显式复制,但肯定会有一个您没有看到的隐式副本.它有可能与你的计算很好地重叠.请注意,您可能需要同步内核调用以确保内核已完成并且您在h_p中具有已修改的内容.


小智 1

使用主机内存会比设备内存慢几个数量级。它具有非常高的延迟和非常有限的吞吐量。例如,当 GTX460 上的设备内存带宽为 108GB/s 时,PCIe x16 的容量仅为 8GB/s