GPU/CUDA:网格的最大块数和每个多处理器的最大驻留块数
Posted
技术标签:
【中文标题】GPU/CUDA:网格的最大块数和每个多处理器的最大驻留块数【英文标题】:GPU/CUDA: Maximum number of blocks of a grid and Maximum number of resident blocks per multiprocessor 【发布时间】:2013-07-13 04:30:32 【问题描述】:我的 GPU 能力为 2.1,有 2 个 SM,每个 SM 有 48 个内核。根据CUDA-C编程指南中提供的技术规范,网格的最大块数为65535,每个多处理器的最大驻留块数为8。
我对可以启动多少块感到困惑。如果每个 SM 的最大块数为 8,这是否意味着如果只有 2 个 SM,我最多可以启动 16 个块?但是我成功地启动了更多的块。
也许有活动块和非活动块之类的东西?如果这是事实,那么这些块是如何安排的?不活动的是否等到所有 8 个活动块都完成?但这带来了同步问题......
还有一些问题……如果每个 SM 上有 48 个核心,那么可以同时执行 3 个半扭曲。但是共享内存只有 32 个 bank。如果两个线程同时尝试从同一个band读取,即使它们属于不同的half-warp,它们不会产生bankconflict吗?
【问题讨论】:
【参考方案1】:我确实迟到了,但由于之前的答案未被接受,我提供了一个希望帮助其他用户解决同样问题的答案。
一个SM可以包含的最大块数是指给定时间内的最大活动块数。块可以组织成一维或二维网格,每个维度最多包含 65,535 个块,但 gpu 的 SM 将只能容纳一定数量的块。此限制以两种方式与您的 Gpu 的计算能力相关联。
-
CUDA 规定的硬件限制。
每个 gpu 允许每个 SM 的最大块限制,无论它包含的线程数和使用的资源量如何。例如,计算能力为 2.0 的 GPU 的限制为 8 Blocks/SM,而计算能力为 7.0 的 GPU 的限制为 32 Blocks/SM。这是您可以实现的每个 SM 的最佳活动块数:我们称之为 MAX_BLOCKS。
-
限制来自每个块使用的资源量。
一个块由线程组成,每个线程使用一定数量的寄存器:它使用的寄存器越多,包含它的块使用的资源数量就越多。类似地,分配给块的共享内存量增加了块需要分配的资源量。一旦超过某个值,一个块所需的资源数量将如此之大,以至于 SM 将无法分配 MAX_BLOCKS 允许的尽可能多的块:这意味着每个块所需的资源量是有限的每个 SM 的最大活动块数。
如何找到这些界限?
CUDA 也考虑过这一点。在他们的网站上提供了Cuda Occupancy Calculator file,您可以通过它发现按计算能力分组的硬件限制。您还可以输入块使用的资源量(线程数、每个线程的寄存器、共享内存的字节数)并获取有关活动块数的图表和重要信息。
【讨论】:
所以我仍然不能 100% 确定这一点,但一个非常简单的概念是我自己对这一切的理解的一堵砖墙:块的基本目的实际上是与 SM 中的一块共享内存进行映射,并一直驻留直到完成。这就是块的存在目的(共享内存的分配和使用机制),也是为什么块大小对吞吐量影响如此之大以及为什么应该谨慎选择它的原因。【参考方案2】:根据 CUDA-C 编程指南中提供的技术规范,网格的最大块数为 65535,每个多处理器的最大驻留块数为 8。
我对可以启动多少块感到困惑。如果每个 SM 的最大块数为 8,那是不是意味着如果只有 2 个 SM,我最多可以启动 16 个块?
最大块数(网格中的每个维度)是 CUDA 调度程序可以处理的限制。除了最近的 Kepler GPU,每个维度的限制是 65535。
实际上,活动块的数量取决于很多事情。每个 SM 可以启动的块数量存在硬性限制,但如果每个块使用大量共享内存、寄存器或线程,数量也可以更小。
调度程序会切换非活动块(即由于各种原因而停止的块)并切换到活动块。为了使 SM 尽可能活跃,启动了大量的块而不是物理上可能的。
但这会带来同步问题...
永远不要假设 CUDA 块是按顺序启动的。它们可以乱序处理,唯一的同步点是在主机上完成内核和cudaDeviceSynchronize
。
【讨论】:
“它们可以乱序处理”是否意味着非活动块的上下文和资源(即共享内存和寄存器)也必须保存在 SM 中? 我无法解释这些东西是如何在内部实现的。我有根据的猜测是,如果共享内存/寄存器的使用有压力,切换会更加保守。 @Pavan 计算能力 1.0 - 3.0 以确定的顺序处理块(因架构而异)。计算能力 3.x 支持 CUDA 动态并行 (CDP) 的乱序处理。 CDP 确实需要额外的内存分配来保存关闭块状态,以允许子内核向前推进。以上是关于GPU/CUDA:网格的最大块数和每个多处理器的最大驻留块数的主要内容,如果未能解决你的问题,请参考以下文章
有啥方法可以为 CuPy 计算设置线程数、块数和网格数?如何?