5

这个问题源于在内核中观察到的理论占用率和实际占用率之间的差异。我知道计算器和 nvprof 之间的不同占用率,以及关于从块到 CUDA 中的 SM 分布的详细信息的问题

让我们考虑一个计算能力 = 6.1 和 15 个 SM 的 GPU(GTX TITAN、Pascal 架构、芯片组 GP104)。让我们考虑一个 2304 个元素的小问题。

如果我们配置一个有 512 个线程的内核,那么每个线程将处理一个元素,我们需要 5 个块来操作所有数据。而且内核是如此之小,以至于在资源使用方面没有任何限制,无论是寄存器还是共享内存。

因此,理论占用率为 1,因为可以在一个 SM(2048 个线程)中分配四个并发块,从而导致 2048 / 32 = 64 个活动扭曲(最大值)。

然而,实现的占用率(由 nvidia 分析器报告)约为 0.215,这可能与块映射到 SM 的方式有关。那么,当块的数量小于可用的 SM 时,如何将块调度到 CUDA 中的 SM 中?

选项 1.-将 4 个 512 线程块调度到一个 SM 中,将 1 个 512 块调度到另一个 SM 中。在这种情况下,占用率为 (1 + 0.125) / 2 = 0.56。我认为最后一个块只有 512 个线程中的 256 个处于活动状态,才能到达数组的最后 256 个元素,并且它在第二个 SM 中分配。因此,考虑到经纱粒度,只有 8 个经纱处于活动状态。

选项 2.-将每个 512 块调度到不同的 SM。既然我们有 15 个 SM,为什么只有一个 SM 有很多块?在这种情况下,我们每个 SM 有 512 / 32 = 16 个活动经线(最后一个除外,它只有 256 个活动线程)。因此,我们在四个 SM 中实现了 0.25 的占用率,在最后一个 SM 中实现了 0.125,导致 (0.25 + 0.25 + 0.25 + 0.25 + 0.125) / 5 = 0.225。

选项 2 更接近视觉分析器报告的占用率,我们认为这是幕后发生的事情。无论如何,值得一问:当块数少于可用 SM 时,如何将块调度到 CUDA 中的 SM 中?是否记录在案?

-- 请注意,这不是家庭作业。这是使用不同第三方库的项目中的真实场景,这些库在由多个内核组成的管道的某些步骤中需要处理少量元素。

4

1 回答 1

1

正如几年来对该问题发表的评论中所述,块调度程序的行为是未定义的,并且不能保证从硬件一代到硬件一代、驱动程序/运行时版本到驱动程序/运行时版本,甚至是相同的平台到平台。

当然可以使用汇编指令来检测代码以提取时钟和 SM ID 并运行一些案例以查看您的设备上发生了什么。正如 Greg Smith 在评论中指出的那样,您可能会得出这样的结论:调度程序首先工作广度,将 SM 填充到最大可用占用率,但不一定总是这样。最终,您尝试利用您的发现构建的任何启发式方法都将依赖于未定义的行为。

[从评论中收集并添加为社区 wiki 条目,以将问题从 CUDA 标签的未回答队列中删除]

于 2020-06-05T07:45:39.800 回答