我试图弄清楚使用 cudaHostAlloc (或 cudaMallocHost?) 是否合适。
我正在尝试运行一个内核,其中我的输入数据超过 GPU 上的可用数据量。
我的 cudaMallocHost 空间可以大于 GPU 上的空间吗?如果没有,假设我分配了我需要的 1/4 空间(适合 GPU),那么使用固定内存有什么优势吗?
我本质上仍然必须从 1/4 大小的缓冲区复制到我的全尺寸 malloc'd 缓冲区中,这可能不会比仅使用正常的 cudaMalloc 更快,对吧?
对于使用 cudaMallocHost,以下典型使用场景是否正确:
- 分配固定主机内存(我们称之为“h_p”)
- 用输入数据填充 h_p -
- 获取 GPU 上 h_p 的设备指针
- 使用该设备指针运行内核来修改数组的内容-
- 像平常一样使用 h_p,现在已经修改了内容 -
那么 - 在第 4 步和第 5 步之间没有副本必须满意,对吧?
如果这是正确的,那么我可以看到至少一次适合 GPU 的内核的优势
内存传输是影响 CUDA 应用程序性能的一个重要因素。cudaMallocHost可以做两件事:
- 分配固定内存:这是 CUDA 运行时可以跟踪的页锁定主机内存。如果以这种方式分配的主机内存涉及
cudaMemcpy
作为源或目标,CUDA 运行时将能够执行优化的内存传输。
- 分配映射内存:这也是页锁定内存,可以直接在内核代码中使用,因为它映射到 CUDA 地址空间。为此,您必须设置
cudaDeviceMapHost
标志使用cudaSetDeviceFlags在使用任何其他 CUDA 函数之前。 GPU内存大小不限制映射的主机内存的大小。
我不确定后一种技术的性能。它可以让你很好地重叠计算和通信。
如果您访问内核中的块内存(即您不需要整个数据,而只需要一部分),您可以使用利用异步内存传输的多缓冲方法cudaMemcpyAsync通过在 GPU 上拥有多个缓冲区:在一个缓冲区上进行计算,将一个缓冲区传输到主机,同时将一个缓冲区传输到设备。
使用时我相信您关于使用场景的断言是正确的cudaDeviceMapHost
分配类型。您不必执行显式副本,但肯定会有您看不到的隐式副本。它有可能与您的计算很好地重叠。请注意,您可能需要同步内核调用以确保内核完成并且您在 h_p 中拥有修改后的内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)