CUDA:关于活动扭曲(活动块)以及如何选择块大小的问题

Posted

技术标签:

【中文标题】CUDA:关于活动扭曲(活动块)以及如何选择块大小的问题【英文标题】:CUDA: question about the active warps (active blocks) and how to choose the block size 【发布时间】:2011-07-19 17:07:38 【问题描述】:

假设一个 CUDA GPU 可以在一个多处理器上同时有 48 个活动扭曲,即一个扭曲的 48 个块,或 2 个扭曲的 24 个块,...,因为来自多个块的所有活动扭曲都被调度执行,它看来block的大小对于GPU的占用来说并不重要(当然应该是32的倍数),不管是32、64还是128都没有区别吧?那么块的大小只是由计算任务和资源限制(共享内存还是寄存器)决定?

【问题讨论】:

与***.com/questions/4391162/…相关 @Heatsink 这个问题是不同的,因为考虑到每个 mp 有最大数量的活动扭曲(并且,我将添加,考虑到多个块可以驻留在一个 mp)。 目前我的理解是,无论计算任务和要求如何,您都可以选择块大小来增加受 MINresource (shared/register); 限制的占用率;最大活动经线(例如 48); max active blocks (e.g. 8) * block size 以及将块平均分配到多处理器的数量。 【参考方案1】:

有多个因素值得考虑,但您忽略了。

SM 上的活动块数有限制。当前限制为 8(所有设备),因此如果您想实现完全占用,您的块不应小于:3-warps(设备 1.0、1.1)、4-warps(1.2、1.3)和 6-warps (2.x) 根据设备的不同,每个多处理器有 8K、16K 或 32K 寄存器可用。块越大,块需要多少寄存器的“粒度”就越大。对于大街区,如果不能完全入住,你会损失很多。对于较小的块,损失可能更小。这就是为什么我个人更喜欢 2x256 而不是 1x512。 如果您确实需要在一个块中的 warp 之间进行同步,更大的块可以让您拥有更广泛的同步。 保证在单个多处理器上调度单个块。如果它的所有扭曲都有一些公共数据(例如控制变量),您可以减少全局内存获取的数量。另一方面,当您创建大量小块时,每个小块可能都需要分别加载相同的数据。在有一些缓存的 Fermi 上,它不如在 GF-200 系列上重要。但是请记住,由于有这么多的多处理器,1MB L2 缓存仍然非常非常小!

【讨论】:

是的,我现在明白了,我忽略了块数(8)的限制,无论寄存器/共享内存资源如何,如果我为每个块分配 32 个(1 个扭曲),那么活动扭曲是只有 8 条经线。【参考方案2】:

没有。 块大小确实很重要。

如果您的块大小为 32 个线程,则占用率非常低。 如果您的块大小为 256,则占用率很高。这意味着所有 256 个都同时处于活动状态。 超过 256 个线程/块很少会有所作为。

由于所涉及的架构很复杂,因此使用您的软件对其进行测试始终是最好的方法。

【讨论】:

我觉得没这么简单。是的,块尺寸确实很重要,是的,测试是最好的方法。但是,我不认为每个块更少的线程一定意味着更低的占用率。一个 mp 上可以驻留多个街区,从而提高占用率。 是的,没那么简单,还有资源等其他因素会影响整体入住率。但答复回答了恕我直言的问题。 我理解问题是——“假设我们启动 48 个线程/SM,我们如何将任务分成块是否重要?”

以上是关于CUDA:关于活动扭曲(活动块)以及如何选择块大小的问题的主要内容,如果未能解决你的问题,请参考以下文章

为啥 CUDA 中网格中的所有块的 Blockdim 都应该相同?

CUDA中的线程和块结构以及如何分配具有不同结构的线程(c ++)

“cudaOccupancyMaxActiveBlocksPerMultiprocessor” API 返回的活动块数值的意义?

CUDA 学习(十九)优化策略4:线程使用计算和分支

CUDA 学习(十九)优化策略4:线程使用计算和分支

(py)CUDA中的网格和块尺寸[重复]