如何确定CUDA流阻塞的原因

JSo*_*oet 7 cuda gpu

我试图将我从Tesla T10处理器(计算能力1.3)编写的算法切换到Tesla M2075(计算能力2.0).切换时我惊讶地发现我的算法速度变慢了.我分析了它,发现它似乎是因为在新机器上cuda流是阻塞的.我的算法有3个主要任务可以拆分并且并行运行:内存重组(可以在CPU上完成),从主机到设备的内存复制,以及设备上的内核执行.在旧机器上拆分流允许3个任务重叠如此(来自NVidia Visual Profiler的所有屏幕截图): 正确的流执行

但是在新机器上,流在开始CPU计算之前阻塞,直到前一个内核完成执行,如下所示: 3流执行

你可以看到顶行,所有橙色块都是cudaStreamSynchronize调用,它们阻塞直到前一个内核完成执行,即使该内核位于一个完全不同的流上.它似乎适用于第一次通过流并正确并行化,但在此之后问题开始,所以我想也许它阻塞了某些东西,我试图增加流的数量,这给了我这个结果: 12流执行

在这里你可以看到,由于某种原因,只有前4个流被阻塞,之后它开始正常并行化.作为最后一次尝试,我试图通过仅使用前4个流仅一次然后切换到使用后面的流但仍然不起作用并且它仍然停止每4个流同时让其他流同时执行来破解它: 10个流执行

因此,我正在寻找任何可能导致此问题以及如何诊断它的想法.我对我的代码感到厌倦,我不认为那是一个错误,虽然我可能弄错了.每个流都封装在它自己的类中,并且只引用一个cudaStream_t,它是该类的成员,所以我看不出它是如何引用另一个流并阻塞它的.

我不知道版本1.3和2.0之间的流的工作方式有什么变化吗?可能是共享内存没有被释放而且必须等待的东西吗?欢迎任何有关如何诊断此问题的想法,谢谢.

小智 3

如果没有看到代码,我无法完全确定,但看起来您的命令排队顺序可能存在问题。由于 2.x 设备可以同时运行多个内核并同时处理 HtoD 和 DtoH,因此计算能力 1.x 和 2.x 设备处理流的方式略有不同。

如果您按照所有 HtoD、所有计算、所有 DtoH 的顺序排列命令,您将在 Tesla 卡上获得良好的结果(1060 等)。

如果你命令它们复制 HtoD、计算、复制 DtoH、复制 HtoD...等等,你将在费米上得到很好的结果。

开普勒在这两种情况下都表现得同样好。在 Tesla 和 Fermi 的情况下,这在流中确实很重要,我建议阅读这篇 NVIDIA 文章以获取更多信息。跨流重叠可能是一个极其复杂的问题,祝您一切顺利。如果您需要进一步的帮助,对操作入队顺序的一般表示将非常有帮助。