我正在尝试将我从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之间的流的工作方式有哪些变化?可能是共享内存没有被释放而且必须等待的东西吗?欢迎提出任何有关如何诊断此问题的建议,谢谢。
答案 0 :(得分:3)
如果没有看到代码,我无法完全确定,但看起来您可能会遇到排队命令的问题。计算能力1.x和2.x设备处理流的方式略有不同,因为2.x设备可以同时运行多个内核并同时处理HtoD和DtoH。
如果按照顺序将命令排入所有HtoD,所有计算,所有DtoH,您将在特斯拉卡(1060等人)上获得良好的结果。
如果你订购他们复制HtoD,计算,复制DtoH,复制HtoD等等,你将在费米上取得好成绩。
开普勒在两种情况下的表现同样出色。这对特斯拉和费米案件中的流都很重要,我建议阅读this NVIDIA post以获取更多信息。跨越溪流可能是一个非常复杂的问题,我祝福你。如果您需要进一步的帮助,那么排队操作的顺序的一般表示将非常有用。