CUDA零拷贝内存注意事项

时间:2011-02-15 18:03:47

标签: 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. 使用该设备指针运行内核以修改数组的内容 -
  6. 使用正常的h_p,现在已经修改了内容 -
  7. 那么 - 在第4步和第5步之间没有副本可以开心吗?

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

5 个答案:

答案 0 :(得分:6)

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

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

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

CUDA C编程指南和CUDA最佳实践指南均未提及cudaMallocHost分配的数量't 大于设备内存,因此我认为它是可能的。< / p>

从页面锁定内存到设备的数据传输比正常数据传输更快,如果使用写入组合内存则更快。 此外,以这种方式分配的内存可以映射到设备内存空间,无需(手动)复制数据。它会在需要数据时自动发生,因此您应该能够处理更多数据,而不是适合设备内存。

但是,如果页面锁定量构成主机内存的重要部分,则(主机的)系统性能会受到很大影响。

那么何时使用这种技术?,简单:如果数据需要只读一次并且只写一次,请使用它。它会产生性能提升,因为无论如何都要在某个时刻来回复制数据。但是,只要需要存储不适合寄存器或共享内存的中间结果,就会使用cudaMalloc处理适合设备内存的数据块。

答案 3 :(得分:0)

  1. 是的,你可以在cudaMalloc上留下比在gpu上更多的空间。
  2. 固定内存可以具有更高的带宽,但可以降低主机性能。在普通主机内存,固定内存,写入组合内存甚至映射(零复制)内存之间切换非常容易。为什么不首先使用正常的主机内存并比较性能?
  3. 是的,您的使用方案应该有效。
  4. 请记住,全局设备内存访问速度很慢,零拷贝主机内存访问速度更慢。零拷贝是否适合您完全取决于您如何使用内存。

答案 4 :(得分:0)

还考虑使用流来重叠数据传输/内核执行。 这为数据块提供了gpu工作