7

我正在尝试将我编写的算法从 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 之间的流工作方式是否有一些我不知道的变化?可能是共享内存没有被释放而不得不等待的东西吗?欢迎任何有关如何诊断此问题的想法,谢谢。

4

1 回答 1

3

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

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

如果您命令他们复制 HtoD、计算、复制 DtoH、复制 HtoD ......等等,您将在 Fermi 上获得良好的结果。

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

于 2013-06-14T15:51:05.353 回答