CUDA内核调用是同步还是异步的?

32
我看到可以使用内核启动来同步不同的块,即如果我想让所有块在进行操作2之前完成操作1,则应该将操作1放置在一个内核中,操作2放置在另一个内核中。这样,我可以在块之间实现全局同步。然而,CUDA C编程指南提到内核调用是异步的,即CPU不等待第一个内核调用完成,因此CPU也可以在第一个内核完成之前调用第二个内核。但是,如果这是真的,那么我们无法使用内核启动来同步块。请告诉我我错在哪里。
3个回答

46

从CPU的角度来看,内核调用是异步的,因此如果您连续调用两个内核,则第二个内核将在不等待第一个内核完成的情况下被调用。这仅意味着控制立即返回到 CPU。

在GPU方面,如果您没有指定不同的流以执行内核,则它们将按照调用顺序执行内核(如果您没有指定流,则它们都进入默认流并逐个执行)。只有在第一个内核完成后,第二个内核才会执行。

这种行为适用于具有计算能力2.x的设备,该设备支持并发内核执行。在其他设备上,即使内核调用仍然是异步的,内核执行也始终是顺序执行。

请查看CUDA C编程指南第3.2.5节,这是每个CUDA程序员都应该阅读的内容。


15

被接受的答案并不总是正确的。

在大多数情况下,内核启动是异步的。但在以下情况下,它是同步的。而且这些情况经常被人忽略。

  • 环境变量CUDA_LAUNCH_BLOCKING等于1。
  • 使用分析器(nvprof),没有启用并发内核分析。
  • 涉及未锁定页面的主机内存的内存复制。

程序员可以通过将CUDA_LAUNCH_BLOCKING环境变量设置为1来全局禁用所有运行在系统上的CUDA应用程序的内核启动异步性。此功能仅供调试目的使用,不应用作使生产软件可靠运行的方式。

如果通过分析器(Nsight、Visual Profiler)收集硬件计数器,则内核启动是同步的,除非启用了并发内核分析。如果涉及未锁定页面的主机内存,则异步内存复制也将是同步的。

来自NVIDIA CUDA编程指南(http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#concurrent-execution-host-device)。


-3

自2.0 CUDA能力版本起,支持并发内核执行。

此外,可以在所有warp内核完成之前更早地返回到CPU代码。

在这种情况下,您可以自己提供同步。


并发内核执行与异步内核执行完全不同。不,您不能自己提供同步。 - wyphan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接