我有一个处理大量数据的CUDA内核。 由于我不能一次传输所有数据,我必须将它们分成块并处理它们chunk并更新GPU上的输出。 我正在解析文件中的输入数据。 我在想是否可以通过在主机和GPU中都有两个缓冲区来重叠块的内存传输。在处理一个卡盘时,我可以读取另一个卡盘,将其传输到GPU并将内核启动到同一个流。 我的问题是内核的执行时间比解析数据并将其传输到GPU要慢。考虑到memcpys没有阻塞这一事实,我如何确保memcpys不会写入内核使用的数据?
//e.g. Pseudocode
//for every chunk
//parse data
//cudaMemcpyAsync ( dev, host, size, H2D )
//launch kernel
//switch_buffer
//copy result from device to host
提前谢谢。
答案 0 :(得分:0)
在内核启动后,只需在cudaDeviceSynchronize()
处插入显式同步点即可。
这样,您实际上是在开始内存传输并同时启动内核。传输将转到一个缓冲区,内核将在另一个缓冲区上运行。 cudaDeviceSynchronize()会等到两个都完成,此时你会交换缓冲区并重复。
当然,您还需要将结果从设备复制到循环内的主机,并添加逻辑来处理第一次迭代,当没有内核要处理的数据时,以及最后一次迭代,当没有时要复制的数据越多,但仍需要处理一个缓冲区。这可以通过循环中的逻辑或通过部分展开循环来完成,以专门编写第一次和最后一次迭代。
修改强>
通过将同步点移动到cudaMemcpyAsync()
之前以及文件读取和解析之后,您允许内核也重叠处理的那部分(如果内核运行的时间足够长)。