技术开发 频道

CUDA的Threading:Block和Grid设定

  建议的数值?

  在 Compute Capability 1.0/1.1 中,每个 SM 最多可以同时管理 768 个 thread(768 active threads)或 8 个 block(8 active blocks);而每一个 warp 的大小,则是 32 个 thread,也就是一个 SM 最多可以有 768 / 32 = 24 个 warp(24 active warps)。到了 Compute Capability 1.2 的话,则是 active warp 则是变为 32,所以 active thread 也增加到 1024。

  在这里,先以 Compute Capability 1.0/1.1 的数字来做计算。根据上面的数据,如果一个 block 里有 128 个 thread 的话,那一个 SM 可以容纳 6 个 block;如果一个 block 有 256 个 thread 的话,那 SM 就只能容纳 3 个 block。不过如果一个 block 只有 64 个 thread 的话,SM 可以容纳的 block 不会是 12 个,而是他本身的数量限制的 8 个。

  因此在 Compute Capability 1.0/1.1 的硬件上,决定 block 大小的时候,最好让里面的 thread 数目是 warp 数量(32)的倍数(可以的话,是 64 的倍数会更好);而在一个 SM 里,最好也要同时存在复数个 block。如果再希望能满足最多 24 个 warp 的情形下,block 里的 thread 数目似乎会是 96(一个 SM 中有 8 个 block)、128(一个 SM 中有 6 个 block)、192(一个 SM 中有 4 个 block)、256(一个 SM 中有 3 个 block) 这些数字了~

  而官方的建议则是一个 block 里至少要有 64 个 thread,192 或 256 个也是通常比较合适的数字(请参考 Programming Guide)。

  但是是否这些数字就是最合适的呢?其实也不尽然。因为实际上,一个 SM 可以允许的 block 数量,还要另外考虑到他所用到 SM 的资源:shared memory、registers 等。在 G80 中,每个 SM 有 16KB 的 shared memory 和 8192 个 register。而在同一个 SM 里的 block 和 thread,则要共享这些资源;如果资源不够多个 block 使用的话,那 CUDA 就会减少 Block 的量,来让资源够用。在这种情形下,也会因此让 SM 的 thread 数量变少,而不到最多的 768 个。

  比如说如果一个 thread 要用到 16 个 register 的话(在 kernel 中宣告的变量),那一个 SM 的 8192 个 register 实际上只能让 512 个 thread 来使用;而如果一个 thread 要用 32 个 register,那一个 SM 就只能有 256 个 thread 了~而 shared memory 由于是 thread block 共享的,因此变成是要看一个 block 要用多少的 shread memory、一个 SM 的 16KB 能分给多少个 block 了。

  所以虽然说当一个 SM 里的 thread 越多时,越能隐藏 latency,但是也会让每个 thread 能使用的资源更少。因此,这点也就是在优化时要做取舍的了。

0
相关文章