我有一些疑问。
最近在用CUDA做一个程序。
在我的程序中,Host 上有一个用 std::map(string, vector(int)) 编程的大数据。
通过使用这些数据,一些向量(int)被复制到GPU全局内存并在GPU上处理
处理后,在 GPU 上生成一些结果,并将这些结果复制到 CPU。
这些都是我的节目安排。
- cudaMemcpy( ... , cudaMemcpyHostToDevice)
- 内核函数(只有将必要的数据复制到GPU全局内存时才能完成内核函数)
- cudaMemcpy( ... , cudaMemcpyDeviceToHost)
- 重复1~3步骤1000次(对于另一个数据(向量))
但我想减少处理时间。
所以我决定在我的程序中使用 cudaMemcpyAsync 函数。
在搜索了一些文档和网页后,我意识到要使用 cudaMemcpyAsync 函数将数据复制到 GPU 全局内存的主机内存必须分配为固定内存。
但我的程序正在使用 std::map,所以我无法将此 std::map 数据固定到内存中。
因此,我没有使用它,而是制作了一个缓冲区数组类型的固定内存,并且该缓冲区始终可以处理复制向量的所有情况。
最后我的程序就这样运行了。
- Memcpy(使用循环将数据从 std::map 复制到缓冲区,直到将整个数据复制到缓冲区)
- cudaMemcpyAsync( ... , cudaMemcpyHostToDevice)
- kernel(只有当整个数据复制到GPU全局内存时才能执行内核函数)
- cudaMemcpyAsync( ... , cudaMemcpyDeviceToHost)
- 重复1~4步骤1000次(对于另一个数据(向量))
我的程序变得比之前的情况快得多。
但问题(我的好奇心)就在这一点上。
我尝试以类似的方式制作另一个程序。
- Memcpy(仅针对一个向量将数据从 std::map 复制到缓冲区)
- cudaMemcpyAsync( ... , cudaMemcpyHostToDevice)
- 循环1~2,直到全部数据复制到GPU全局内存
- kernel(只有当必要的数据复制到GPU全局内存时才能执行内核函数)
- cudaMemcpyAsync( ... , cudaMemcpyDeviceToHost)
- 重复 1~5 步骤 1000 次(对于另一个数据(向量))
该方法比上面讨论的方法快约 10%。
但我不知道为什么。
我认为 cudaMemcpyAsync 只能与内核函数重叠。
但我的情况我认为不是。而不是看起来可以在 cudaMemcpyAsync 函数之间重叠。
抱歉我的问题很长,但我真的很想知道为什么。
有人可以教我或向我解释什么是确切的设施“cudaMemcpyAsync”以及哪些功能可以与“cudaMemcpyAsync”重叠?
cudaMemcpyAsync 的复制活动(以及内核活动)可以与any主机代码。此外,进出设备的数据复制(通过 cudaMemcpyAsync)可以与内核活动重叠。所有 3 个活动:主机活动、数据复制活动和内核活动,可以彼此异步完成,并且可以彼此重叠。
正如您所看到和演示的,主机活动和数据复制或内核活动可以以相对简单的方式相互重叠:内核启动立即返回到主机,cudaMemcpyAsync 也是如此。然而,为了获得数据复制和内核活动之间的最佳重叠机会,有必要使用一些额外的概念。为了获得最佳重叠机会,我们需要:
- 固定的主机内存缓冲区,例如通过 cudaHostAlloc()
- 使用 cuda 流来分离各种类型的活动(数据复制和内核计算)
- 使用 cudaMemcpyAsync (而不是 cudaMemcpy)
当然,你的工作也需要以可分离的方式分解。这通常意味着,如果您的内核正在执行特定功能,您可能需要多次调用该内核,以便每次调用都可以处理单独的数据。例如,这允许我们在第一次内核调用正在处理数据块 A 时将数据块 B 复制到设备。这样我们就有机会将数据块 B 的副本与数据块 A 的内核处理重叠。
与 cudaMemcpyAsync 的主要区别(与 cudaMemcpy 相比)是:
- 它可以在任何流中发出(它需要一个流参数)
- 通常,它将控制权返回给主机立即地(就像内核调用一样)而不是等待数据复制完成。
第 1 项是必要的功能,以便数据复制可以与内核计算重叠。第 2 项是必要的功能,以便数据复制可以与主机活动重叠。
尽管复制/计算重叠的概念非常简单,但在实践中实现需要一些工作。如需其他参考,请参阅:
-
重叠复制/计算部分CUDA 最佳实践指南。
- 示例代码显示复制/计算重叠的基本实现.
- 显示完整的示例代码多/并发内核复制/计算重叠场景.
请注意,上面的一些讨论是基于具有计算能力 2.0 或更高的设备(例如并发内核)。此外,不同的设备可能有 1 个或 2 个复制引擎,这意味着同时复制到设备并复制从设备仅在某些设备上可行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)