我正在尝试将我编写的算法从 Tesla T10 处理器(计算能力 1.3)切换到 Tesla M2075(计算能力 2.0)。在切换时,我惊讶地发现我的算法变慢了。我分析了一下,发现好像是因为新机器上cuda流阻塞了。我的算法有 3 个可以拆分并并行运行的主要任务:内存重组(可以在 CPU 上完成)、从主机到设备的内存复制以及设备上的内核执行。在旧机器上拆分流允许 3 个任务像这样重叠(所有屏幕截图来自 NVidia Visual Profiler):
然而,在新机器上,流在开始 CPU 计算之前会阻塞,直到前一个内核完成执行,如下所示:
您可以看到顶行,所有橙色块都是 cudaStreamSynchronize 调用,这些调用会阻塞直到前一个内核完成执行,即使该内核位于完全不同的流上。它似乎适用于第一次运行流并正确并行化,但在那之后问题开始了,所以我认为它可能阻塞了某些东西,我试图增加流的数量,这给了我这个结果:
在这里您可以看到由于某种原因只有前 4 个流被阻塞,之后它开始正确并行化。作为最后一次尝试,我试图通过只使用前 4 个流一次然后切换到使用后面的流来破解它,但这仍然不起作用,它仍然每 4 个流停止,同时让其他流同时执行:
所以我正在寻找关于什么可能导致这个问题以及如何诊断它的任何想法。我仔细研究了我的代码,尽管我可能弄错了,但我认为这不是一个错误。每个流都封装在自己的类中,并且只引用了一个 cudaStream_t,它是该类的成员,所以我看不出它如何引用另一个流并阻止它。
版本 1.3 和 2.0 之间的流工作方式是否有一些我不知道的变化?可能是共享内存没有被释放而不得不等待的东西吗?欢迎任何有关如何诊断此问题的想法,谢谢。