CUDA 确定每个块的线程、每个网格的块

2024-02-11

我是 CUDA 范式的新手。我的问题是确定每个块的线程数和每个网格的块数。这是否需要一些艺术和尝试?我发现许多例子似乎为这些事情选择了任意的数字。

我正在考虑一个问题,我可以将任意大小的矩阵传递给乘法方法。这样,C 的每个元素(如 C = A * B)将由单个线程计算。在这种情况下,您如何确定线程/块、块/网格?


一般来说,您希望调整块/网格的大小以匹配您的数据,并同时最大化占用率,即一次有多少个线程处于活动状态。影响占用的主要因素是共享内存使用、寄存器使用和线程块大小。

支持 CUDA 的 GPU 的处理能力分为 SM(流式多处理器),SM 的数量取决于实际的卡,但为了简单起见,这里我们将重点关注单个 SM(它们的行为都相同)。每个 SM 都有有限数量的 32 位寄存器、共享内存、最大数量的活动块以及最大数量的活动线程。这些数字取决于 GPU 的 CC(计算能力),可以在维基百科文章的中间找到http://en.wikipedia.org/wiki/CUDA http://en.wikipedia.org/wiki/CUDA.

首先,线程块大小应始终是 32 的倍数,因为内核在 warp 中发出指令(32 个线程)。例如,如果您的块大小为 50 个线程,GPU 仍将向 64 个线程发出命令,而您只是在浪费它们。

其次,在担心共享内存和寄存器之前,请尝试根据与卡的计算能力相对应的最大线程和块数来确定块的大小。有时有多种方法可以做到这一点...例如,CC 3.0 卡的每个 SM 可以有 16 个活动块和 2048 个活动线程。这意味着,如果每个块有 128 个线程,则在达到 2048 个线程限制之前,您可以在 SM 中容纳 16 个块。如果您使用 256 个线程,则只能容纳 8 个线程,但您仍然使用所有可用线程,并且仍然会完全占用。然而,当达到 16 个块限制时,每个块使用 64 个线程将仅使用 1024 个线程,因此只有 50% 的占用率。如果共享内存和寄存器使用不是瓶颈,那么这应该是您主要关心的问题(而不是数据维度)。

关于网格的主题...网格中的块分布在 SM 上以开始,然后剩余的块被放入管道中。一旦SM中有足够的资源来获取块,块就会被移入SM进行处理。换句话说,当 SM 中的块完成时,新的块就会被移入。您可以提出这样的论点:较小的块(上一个示例中的 128 个而不是 256 个)可能会更快完成,因为特别慢的块会占用更少的资源,但是这很大程度上取决于代码。

关于寄存器和共享内存,请查看接下来的内容,因为它可能会限制您的占用。共享内存对于整个 SM 来说是有限的,因此请尝试以允许尽可能多的块仍然适合 SM 的数量来使用它。寄存器的使用也是如此。同样,这些数字取决于计算能力,可以在维基百科页面上找到表格。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CUDA 确定每个块的线程、每个网格的块 的相关文章

随机推荐