这个问题源于内核中观察到的理论占用率和实际占用率之间的差异。我知道计算器和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中的?是否有文档记录?
-- 请注意,这不是作业。这是一个使用不同第三方库的项目中的真实场景,其中某些步骤的流水线由多个内核组成,需要处理少量元素。
考虑一个具有计算能力=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中的?是否有文档记录?
-- 请注意,这不是作业。这是一个使用不同第三方库的项目中的真实场景,其中某些步骤的流水线由多个内核组成,需要处理少量元素。
clock64()
类型的延迟来强制块持续一段时间。 - Robert Crovella