4

我目前正在使用 CUDA 5.0 中引入的新 CUDA 动态并行 (CDP) 功能。我选择了N-queens 谜题作为具有高度工作不平衡的树搜索算法的示例,在我看来,这可能会从 CDP 中受益。

我的方法大致如下:对于给定的棋盘配置(在第一行中已经放置了一定数量皇后的棋盘),我启动一个带有多个线程的内核。每个线程尝试给定配置下的子树的一个可能分支,直到给定最大值。深度。如果分支的离开仍然代表一个有效的配置,那么该线程会产生一个子线程网格,用于搜索基于该配置的子树。发现其配置无效的线程(两个或更多皇后可能互相攻击)将终止。如果一个线程成功地将最后一个皇后放在板上,它会增加解决方案计数器。

在启动内核之前,我预先计算了 CPU 上的一些板配置,然后为每个配置启动一个网格。

现在解决问题:我发现我的解决方案比另一个不使用 CDP 的 CUDA 实现要慢得多。所以我启动了 Nsight profiler 来寻找原因。这是我的第一个结果(对于 N=10):

N=10 没有流的 Nsight 分析结果。

显然GPU没有被完全占用。所以我想我需要使用不同的流来启动子网格,以防止它们相互等待。以下是为每个子网格启动使用新流时的分析结果:

在此处输入图像描述

这看起来更密集(并且更快),但我仍然不太明白这种模式的原因。为什么在一些发布之间(尤其是最后)会有这么多的闲聊?

但它变得更加陌生。当我将 N(以及工作负载)增加到 13 时,模式如下所示:

在此处输入图像描述

有人知道 CDP 在内部是如何工作的吗?有没有我还没有考虑到的隐式同步障碍?还是我读错了探查器输出?我特别好奇在最后一种情况下这个跨越几乎整个执行时间的线程可能是什么。

我也没有找到关于 Nsight Visual Profiler 的任何关于 CDP 输出的文档。关于 Nsight 在那里展示的任何好的参考资料也会有所帮助。

谢谢!

4

1 回答 1

6

我可以回答您的分析器问题。我将参考您问题中的最后一张图片。

“计算”行显示了上下文中发生的所有内核执行的摘要(在您的情况下,您似乎在设备上只有一个上下文,因此计算行显示了设备上的所有活动)。

Compute 行中的子行用于显示并发内核执行(请注意,这对于 CDP 和非 CDP 应用程序都是如此)。这些子行是根据需要动态创建的,具体取决于有多少并发性。在某些子行中放置内核并不表示任何东西......它们只是使用尝试最小化所需子行数量的启发式方法打包。子行的高度也被缩放以保持垂直空间合理。在您的情况下,您在某些时候有很多并发性,所以看起来您有 30 多个子行,这意味着在某些时候您有 30 多个内核在设备上同时执行。

Compute 行的目标是概述 GPU 在一段时间内的繁忙程度。要具体查看正在执行的内核,您需要探索时间轴中的内核行。

内核时间线显示在上下文时间线的正下方。每个主机启动的内核都有一行。与计算行一样,如果需要显示该内核的并发执行,内核行可以具有子行。在 CDP 应用程序的情况下,内核行也可以有子内核行,它们代表从该内核启动的内核。

对于您的示例,我看到一个主机启动的内核“nQue ...”。请注意,此内核有 7 个子行,因为在某些时候有 7 个内核实例同时执行。对于不启动子内核的内核,内核执行由一个实心间隔表示,显示该内核实例在 GPU 上执行的时间。对于启动子内核的内核,内核执行也可以在末尾包含一个空心部分。空心部分表示内核完成执行后等待子内核完成执行的时间。CDP 执行模型要求父内核在所有子内核完成之前不会完成,这就是空心部分所显示的内容。

您可以通过展开父内核时间线来查看确切的父/子关系。请注意“nQue...”时间线行旁边的“+”图标。如果您打开它,您将在时间线行中看到由任何“nQue...”内核启动的所有子内核。如果这些子内核启动了自己的子内核,则可以反过来扩展这些子内核。

如果您想查看特定内核的“家谱”,有两种方法可以做到。您可以选择一个内核,所有祖先和后代都将在内核行和计算行中突出显示。您可以在图像中看到这一点。Ctrl-select 也适用于多选。如果您选择单个内核并右键单击,您可以在菜单中选择“Focus”,这将隐藏除该内核的祖先/后代之外的所有内核。使用同一菜单中的“不专注”来恢复所有内核。

关于您关于长期执行内核的具体问题。它似乎是从主机启动的“nQue ...”实例之一。在不了解代码的情况下,我不能说为什么它执行这么长时间。您可以选择它并使用 Focus 功能来准确查看它正在启动的子内核,也许这会提供一些见解。

于 2013-09-11T17:16:30.603 回答