C++ cuda中的内存计算重叠问题

C++ cuda中的内存计算重叠问题,c++,asynchronous,cuda,parallel-processing,overlap,C++,Asynchronous,Cuda,Parallel Processing,Overlap,我有一个处理大量数据的CUDA内核。 由于我不能一次传输所有数据,我必须将它们分割成块,逐块处理,并在GPU上更新输出。 我正在解析文件中的输入数据。 我在想,如果在主机和GPU中都有两个缓冲区,是否可以重叠块的内存传输。在处理一个chuck时,我可以读取另一个chuck,将其传输到GPU并将内核启动到同一个流。 我的问题是内核的执行时间比解析数据并将其传输到GPU慢。鉴于memcpys没有阻塞,我如何确保memcpys不会写入内核使用的数据 //e.g. Pseudocode //for ev

我有一个处理大量数据的CUDA内核。 由于我不能一次传输所有数据,我必须将它们分割成块,逐块处理,并在GPU上更新输出。 我正在解析文件中的输入数据。 我在想,如果在主机和GPU中都有两个缓冲区,是否可以重叠块的内存传输。在处理一个chuck时,我可以读取另一个chuck,将其传输到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

提前感谢。

在内核启动后,只需插入一个带有
cudaDeviceSynchronize()
的显式同步点即可

这样,您实际上是在启动内存传输的同时启动内核。传输将转到一个缓冲区,内核将在另一个缓冲区上工作。cudaDeviceSynchronize()将等待这两个操作完成,此时您将交换缓冲区并重复

当然,您还需要将结果从设备复制到循环中的主机,并添加逻辑来处理第一次迭代(当内核还没有要处理的数据时),以及最后一次迭代(当没有更多的数据要复制但仍有一个缓冲区要处理时)。这可以通过循环中的逻辑来完成,也可以通过部分展开循环来具体编码第一次和最后一次迭代

编辑:


通过将同步点移动到
cudaMemcpyAsync()
之前和文件读取和解析之后,您可以允许内核也重叠处理的这一部分(如果内核运行足够长)。

我用cudaDeviceSynchronize实现了这一点,但我希望避免它,因为它需要时间。然而,我看不到任何其他方式来确保我想要的。谢谢。@user2117698,如果你像罗杰描述的那样加倍缓冲,那么就不会花费太多额外的时间。传输和计算之间工作负载的平均分配限制了潜在的加速。如果这两个缓冲区足够大,那么启动内核启动和memcpy的开销将被隐藏,性能将达到其传输/处理有界的自然程度。如果您可以选择,不要每次都重复使用相同的内存并切换缓冲区,您可以看看这一点。一种可能性是为每对响应的memcpy和内核启动使用不同的流。此外,您还必须确保使用固定内存!在伪代码中,
cudaMemcpyAsync
中也缺少使用过的cuda流。