24

我知道 CUDA GPU 上有多处理器,其中包含 CUDA 内核。在我的工作场所,我正在使用 GTX 590,它包含 512 个 CUDA 内核、16 个多处理器,并且 warp 大小为 32。所以这意味着每个多处理器中有 32 个 CUDA 内核,它们在同一个 warp 中的相同代码上运行. 最后,每个块大小的最大线程数是 1024。

我的问题是块大小和多处理器计数 - 扭曲大小是如何完全相关的。说一下我对这种情况的理解:例如我在 GTX 590 上分配了 N 个最大 threadPerBlock 大小为 1024 的块。据我从 CUDA 编程指南和其他来源了解,这些块首先由硬件枚举. 在这种情况下,N 个块中的 16 个被分配给不同的多处理器。每个块包含 1024 个线程,硬件调度程序将其中的 32 个线程分配给单个多处理器中的 32 个内核。同一多处理器(warp)中的线程处理同一行代码并使用当前多处理器的共享内存。如果当前32个线程遇到内存读写等片外操作,它们被当前块中的另一组 32 个线程替换。所以,实际上在一个块中有 32 个线程,它们是在任何给定时间在多处理器上完全并行运行,而不是整个 1024。最后,如果一个块完全由多处理器处理,则将 N 个线程块列表中的一个新线程块插入当前多处理器。最后,在 CUDA 内核执行期间,GPU 中总共有 512 个线程并行运行。(我知道如果一个块使用的寄存器比单个多处理器上可用的寄存器多,那么它会被划分为在两个多处理器上工作,但在我们的例子中假设每个块都可以放入单个多处理器。)

那么,我的 CUDA 并行执行模型是否正确?如果没有,有什么问题或遗漏?我想微调我正在做的当前项目,所以我需要整个事情中最正确的工作模型。

4

1 回答 1

19

在我的工作场所,我正在使用 GTX 590,它包含 512 个 CUDA 内核、16 个多处理器,并且 warp 大小为 32。所以这意味着每个多处理器中有 32 个 CUDA 内核,它们在同一个 warp 中的相同代码上运行. 最后,每个块大小的最大线程数是 1024。

GTX590 包含您提到的数字的 2 倍,因为卡上有 2 个 GPU。下面,我重点介绍单芯片。

说一下我对这种情况的理解:例如我在 GTX 590 上分配了 N 个最大 threadPerBlock 大小为 1024 的块。据我从 CUDA 编程指南和其他来源了解,这些块首先由硬件枚举. 在这种情况下,N 个块中的 16 个被分配给不同的多处理器。

块不一定均匀分布在多处理器 (SM) 上。如果您恰好安排了 16 个块,则一些 SM 可以获得 2 或 3 个块,而其中一些则空闲。我不知道为什么。

每个块包含 1024 个线程,硬件调度程序将其中的 32 个线程分配给单个多处理器中的 32 个内核。

线程和内核之间的关系并不是那么直接。每个 SM 中有 32 个“基本”ALU。处理单精度浮点和大多数 32 位整数和逻辑指令的指令。但是只有16个加载/存储单元,所以如果当前正在处理的warp指令是加载/存储,则必须调度两次。而且只有 4 个特殊功能单元,可以做三角函数之类的事情。所以这些指令必须安排 32 / 4 = 8 次。

同一多处理器(warp)中的线程处理同一行代码并使用当前多处理器的共享内存。

不,一个 SM 中可以同时“运行”超过 32 个线程。

如果当前的 32 个线程遇到像内存读写这样的片外操作,它们将被当前块中的另一组 32 个线程替换。因此,在一个单独的块中实际上有 32 个线程在任何给定时间在多处理器上完全并行运行,而不是全部 1024。

不,不仅仅是内存操作会导致扭曲被替换。ALU 也是深度流水线的,因此当仍在流水线中的值发生数据依赖关系时,新的扭曲将被交换。因此,如果代码包含两条指令,其中第二条使用第一条的输出,那么当第一条指令的值通过管道时,扭曲将被搁置。

最后,如果一个块完全由多处理器处理,则将 N 个线程块列表中的一个新线程块插入当前的多处理器。

一个多处理器一次可以处理多个块,但一个块一旦开始处理就不能移动到另一个 MP。块中当前正在运行的线程数取决于该块使用了多少资源。CUDA 占用计算器将根据您的特定内核的资源使用情况告诉您同时有多少块正在运行。

最后,在 CUDA 内核执行期间,GPU 中总共有 512 个线程并行运行。(我知道如果一个块使用的寄存器比单个多处理器上可用的寄存器多,那么它会被划分为在两个多处理器上工作,但在我们的例子中假设每个块都可以放入单个多处理器。)

不,一个块不能被划分为在两个多处理器上工作。整个块总是由单个多处理器处理。如果给定的多处理器没有足够的资源来处理您的内核至少一个块,您将收到内核启动错误并且您的程序将根本无法运行。

这取决于您如何将线程定义为“正在运行”。GPU 通常会有超过 512 个线程同时消耗芯片上的各种资源。

请参阅@harrism 在此问题中的回答:CUDA:总共有多少并发线程?

于 2012-07-19T16:52:39.007 回答