为什么我的GPU程序可以执行,尽管块数量超过了居民块的数量
Why my GPU program can execute, although the number of blocks exceeds the number of resident blocks?
我正在研究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,直到网格中的所有工作完成为止。
- 使用 std::istream_iterator 时,它似乎跳过了空文件行 - 如果可能的话,如何避免这种情况?
- 为什么调试器总是跳过此程序中的一行?
- C++ For Loop在过程中被跳过了.如何解决?
- C 指针设置为地址,但莫名其妙地指出了程序的不同部分中的不同值
- C++跳过了辛线
- 如何在我的代码中修复无穷循环?我认为它跳过了第二个CIN,因此它一直在循环
- QT Qtimeline跳过了第一个框架
- 基于范围的loop和std :: vector.push_back()崩溃了程序
- 输入后,我的程序似乎跳过了第一个IF语句,直接转到ELSE
- C RLE BMP压缩跳过了最后一个字节
- openssl pem_read_rsapublickey和pem_read_rsa_pubkey崩溃了程序
- 提升单元测试似乎跳过了应执行的代码
- C 将数据读取到一个结构,但它跳过了我的一个获取线,使该元素空白
- 为什么sleep in函数忽略了程序中的几个顺序指令
- 为什么我的程序跳过了一个步骤
- 当我采用测试用例数 = 1 时,我的程序终止.其他明智的是,它给出了正确的答案,但跳过了最后一个测试用例
- 为什么我的代码跳过了这个循环
- 请解释:在 for 循环之后跳过了行
- C++编译器似乎跳过了代码行
- 我用Turbo c++编写的c++程序过了一段时间就挂了