49

最大工作组大小和扭曲大小之间有什么关系?假设我的设备有 240 个 CUDA 流处理器 (SP) 并返回以下信息 -

CL_DEVICE_MAX_COMPUTE_UNITS:30

CL_DEVICE_MAX_WORK_ITEM_SIZES:512 / 512 / 64

CL_DEVICE_MAX_WORK_GROUP_SIZE:512

CL_NV_DEVICE_WARP_SIZE:32

这意味着每个流式多处理器(即计算单元)有 8 个 SP。现在warp size = 32 与这些数字有什么关系?

4

3 回答 3

123

直接回答: warp 大小是 warp 中的线程数,它是硬件实现中用于合并内存访问和指令调度的细分。

推荐阅读:

正如@Matias 提到的,我会去阅读CUDA C 最佳实践指南(你必须滚动到它列出的底部)。查看第 164 页附录 G.1 中的表格可能会对您有所帮助。

解释:

CUDA 是在两个级别上提供并行性的语言。你有线程,你有线程块。这在执行内核时最为明显;您需要指定每个线程块的大小以及在内核参数之前的 <<< >>> 之间的线程块数。

CUDA 没有告诉你的是事情实际上发生在四个层次上,而不是两个层次上。在后台,您的线程块实际上分为称为“warp”的子块。这里有一个简短的比喻来帮助解释真正发生的事情:

简要比喻:

假设您是一位对高中生当前的数学能力感兴趣的教育家/研究员/政治家。您的计划是对 10,240 名学生进行测试,但您不能将他们全部放在足球场或其他地方进行测试。细分(并行化)你的数据收集是最容易的——所以你去 20 所不同的高中,要求他们的 512 名高年级学生分别参加数学考试。

高中的数量,20,类似于“块”的数量/“线程块的数量”。老年人的数量,512,类似于每个块中的线程数,也就是“每个块的线程”。

你收集你的数据,这就是你所关心的。您不知道(并且并不真正关心)的是每所学校实际上都细分为教室。因此,您的 512 名高年级学生实际上被分为 16 组,每组 32 人。此外,这些学校都没有真正拥有所需的资源——每个教室只有 16 个计算器。因此,在任何时候,每个教室只有一半的人可以参加您的数学考试。

高级数 512 表示启动 CUDA 内核时请求的每个块的线程数。实现硬件可能会进一步将其划分为 16 个连续的 32 个线程块,以处理请求的线程的全部数量,即 512。数字 32 是 warp 大小,但这可能会因不同的硬件世代而异。

我可以继续延伸愚蠢的规则,比如任何一所学校只有八个教室可以同时参加考试,因为他们只有八位老师。你不能同时抽样超过 30 所学校,因为你只有 30 名监考人员......

回到你的问题:

使用这个比喻,您的程序想要尽可能快地计算结果(您想要收集数学测试)。你发布一个带有一定数量块(学校)的内核,每个块都有一定数量的线程(学生)。您一次只能运行这么多块(收集您的调查回复需要每所学校一名监考人员)。在 CUDA 中,线程块在流式多处理器 (SM) 上运行。变量:告诉你一张特定卡有CL_DEVICE_MAX_COMPUTE_UNITS多少 SM,30 。这因硬件而有很大差异——请查看CUDA C 最佳实践指南的附录 A 中的表格。请注意,无论计算能力如何(1.X 或 2.X),每个 SM 只能同时运行八个块。

线程块具有最大尺寸:CL_DEVICE_MAX_WORK_ITEM_SIZES. 考虑将线程布置在网格中;你不能有超过512 个线程的行。您不能拥有超过512 个线程的列。而且你不能堆叠超过64 个线程。接下来,有一个最大值:CL_DEVICE_MAX_WORK_GROUP_SIZE线程数512,可以在一个块中组合在一起。所以你的线程块的尺寸可能是:

512×1×1

1×512×1

4×2×64

64×8×1

ETC...

请注意,从 Compute Capability 2.X 开始,您的块最多可以有 1024 个线程。最后,变量CL_NV_DEVICE_WARP_SIZE指定扭曲大小,32(每个教​​室的学生人数)。在 Compute Capability 1.X 设备中,内存传输和指令调度发生在Half-Warp粒度(每个教室只有 16 个计算器)。在 Compute Capability 2.0 中,内存传输按Warp分组,因此同时进行 32 次取指,但指令调度仍然仅按Half-Warp分组。对于 Compute Capability 2.1,内存传输指令调度都由Warp进行,32 个线程。这些东西可以并且将会在未来的硬件中发生变化。

所以,我的话!让我们进入正题:

总之:

我已经描述了经纱/线程布局和其他类似内容的细微差别,但这里有几件事要记住。首先,您的内存访问应该以 16 或 32 为一组“可分组”。因此,将块的 X 尺寸保持为 32 的倍数。其次,要充分利用特定 gpu,最重要的是,您需要最大化占用率。没有 5 块 512 线程。并且没有 1,000 个 10 个线程的块。我强烈建议查看基于 Excel 的电子表格(在OpenOffice中也可以使用??我认为??)它会告诉您特定内核调用的 GPU 占用率(线程布局共享内存要求)。我希望这个解释有帮助!

于 2010-09-25T03:02:50.697 回答
3

扭曲大小是多处理器同时执行的线程数。NVIDIA 多处理器可以使用硬件多线程同时从同一块执行多个线程。

考虑 warp 大小很重要,因为所有内存访问都合并为 warp 大小的倍数(32 字节、64 字节、128 字节),这可以提高性能。

CUDA C 最佳实践指南包含有关此类优化的所有技术信息。

于 2010-08-31T14:16:35.067 回答
1

直接回答很简单:在Nvidia中,由THREADs组成的BLOCKs由程序员设置,WARP为32(由32个线程组成),是计算单元同时执行的最小单元。在 AMD 中,WARP 被称为 WAVEFRONT(“波”)。

在 OpenCL 中,WORKGROUPs 表示 CUDA 中的 BLOCK,而且 WORKITEMs 表示 CUDA 中的 THREAD。

于 2016-12-29T10:04:11.857 回答