当CUDA中的块数小于可用的SM时,块是如何被调度到SM中的?

5
这个问题源于内核中观察到的理论占用率和实际占用率之间的差异。我知道计算器和nvprof之间的不同占用率以及CUDA中块到SM分布细节的问题
考虑一个具有计算能力=6.1和15个SM的GPU(GTX TITAN,Pascal架构,芯片组GP104)。让我们考虑一个小的问题规模,2304个元素。
如果我们使用512个线程配置内核,那么每个线程将处理一个元素,我们需要5个块来操作所有数据。由于内核非常小,因此在使用资源方面,无论是寄存器还是共享内存都没有任何限制。
因此,理论上的占用率为1,因为可以在一个SM中分配四个并发块(2048个线程),导致64个活动warp(最大值)。
然而,实际占用率(由nvidia分析器报告)为~0.215,可能与块映射到SM的方式有关。那么,在CUDA中,当块数小于可用SM数时,这些块如何安排在SM中?选项1.-将4个512线程的块调度到一个SM中,另一个SM中放置1个512块。在这种情况下,占用率将为(1 + 0.125)/ 2 = 0.56。我假设最后一个块仅具有256个512线程活动以达到数组的最后256个元素,并且它被分配到第二个SM中。因此,只有8个warp处于活动状态,考虑到warp粒度。 选项2:将每个512块调度到不同的SMs。由于我们有15个SMs,为什么要让一个SMs饱和处理很多块呢?在这种情况下,每个SMs有16个活跃warp(除了最后一个,只有256个活跃线程)。因此,在四个SMs中我们实现了0.25的占用率,在最后一个SMs中实现了0.125的占用率,导致(0.25 + 0.25 + 0.25 + 0.25 + 0.125)/ 5 = 0.225。
选项2更接近可视化分析器报告的占用率,我们认为这就是背后发生的事情。无论如何,值得问一下:当CUDA中的块数少于可用SMs时,块是如何被调度到SMs中的?是否有文档记录?
-- 请注意,这不是作业。这是一个使用不同第三方库的项目中的真实场景,其中某些步骤的流水线由多个内核组成,需要处理少量元素。

3
行为未指定,并且会因CUDA版本和设备类型而异。通常情况下,据我观察,调度程序会先将块调度到空闲的SM上,然后再将其添加到已有块的SM上。 - Robert Crovella
4
通过让每个块记录它启动的SM ID,可以相对简单地观察简单测试用例的块调度/放置。然后,您可以将块数量从1个变为任意数量,然后查看它们是如何被分派的。您可能想使用clock64()类型的延迟来强制块持续一段时间。 - Robert Crovella
2
最好的方法是像@RobertCrovella提到的那样编写自己的工具。通常情况下,块会按广度优先分布,直到GPU满载,然后根据资源可用性进行按需分配。不建议依赖未记录的行为。 - Greg Smith
1个回答

1
正如在这个问题的多年评论中所指出的那样,块调度程序的行为是未定义的,并且不能保证从硬件一代到硬件一代、从驱动程序/运行时版本到驱动程序/运行时版本,甚至从平台到平台都是相同的。当然,可以使用汇编指令来检测时钟和SM ID,并运行一些测试用例以查看设备上发生了什么。正如Greg Smith在评论中指出的那样,您可能会得出结论,调度程序按广度优先方式工作,填充SM到最大可用占用率,但它并不总是这样。最终,任何试图利用您的发现构建的启发式方法都将依赖于未定义的行为。[从评论中组合而成,并添加为社区wiki条目,以使CUDA标记的问题脱离未回答的队列]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接