为什么我的GPU程序可以执行,尽管块数量超过了居民块的数量

Why my GPU program can execute, although the number of blocks exceeds the number of resident blocks?

本文关键字:过了 程序 GPU 我的 执行 为什么      更新时间:2023-10-16

我正在研究GPU Tesla M6。根据其数据表,特斯拉M6有12位多处理器,每个处理器最多拥有32个居民块。因此,整个设备上居民的总块最大数量为384。

现在,我有一个大小(512,1408(的数据矩阵。我写了一个内核,并将每个街区的线程数设置为64(1D块,每个线程一个数据元素(,因此1D Gird大小为512*1408/64 = 11264块,这远远超出了居民块的数量在GPU上。但是,整个程序仍然可以运行并输出正确的结果。

我想知道为什么代码可以执行,尽管实际数量超过了居民?这意味着性能恶化吗?你能向我详细解释吗?谢谢!

gpu可以容纳比根据您的计算可以居住的更多块。

GPU在SMS上加载尽可能多的块,其余的等待排队等待。当街区完成短信和退休工作时,他们为从队列中选出新块并成为"居民"的空间。最终,GPU以这种方式进行处理。

这种方法不一定有任何问题;它是GPU编程的典型特征。这不一定意味着性能恶化。但是,调整内核的一种方法是根据"居民"选择多少块数量。如果正确完成,可以居住多少居民的计算比您的概述更为复杂。它需要占用分析。CUDA提供了在运行时进行此分析的占用API。

这种方法还需要设计可以使用任意尺寸或固定尺寸网格完成工作的内核,而不是根据问题大小选择的网格大小。一种典型的方法是网格式循环。

如果您将基于网格循环(网格循环(等内核设计结合在一起,并根据占用分析在运行时选择块,那么您只能使用GPU上"居民"的块完成工作;无需在队列中等待。这可能会或可能没有任何切实的绩效好处。只有通过基准测试,您才能确定。

我建议在询问后续问题之前阅读我链接的两篇文章。在cuda标签上也有很多问题讨论此答案中的概念。

线程块中的线程可以相互依赖。诸如合作组之类的编程模型允许大组比线块。网格中的螺纹块数量可能是驻留螺纹块数量的数量级(例如,最小值为1个螺纹块,GV100支持84 x 32 2688居民螺纹块(。

计算工作分配器将线程块分配给SMS。如果电网被抢占,则保存状态并随后恢复。当螺纹块中的所有线程都完成螺纹块资源(WARP插槽,寄存器,共享内存(时,并通知了计算工作分配器。计算工作分销商将继续将线程块分配给SMS,直到网格中的所有工作完成为止。