我们都知道GPGPU有几个stream multiprocesssors(SM)
,每个人在讨论其硬件架构时都有很多stream processors(SP)
。但它在NVDIA的block
编程模型中引入了另一种概念thread
和CUDA
。
我们也知道block
对应SM
而thread
对应SP
,当我们启动CUDA kernel
时,我们将内核配置为{ {1}}。我已经写了kernel<<<blockNum, threadsNum>>>
这样的程序近两个月了。但我还有很多问题。一个优秀的程序员永远不会对无bug程序感到满意,他们想深入研究并了解程序的行为。
以下问题:
假设GPU有14个SM,每个SM有48个SP,我们有这样的内核:
CUDA
和__global__ void double(int *data, int dataNum){
unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
while(tid < dataNum){
data[tid] *= 2;
tid += blockDim.x + blockIdx.x;
}
}
是一个1024 * 1024 int数的数组,内核配置为&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&gt;&gt;&gt;&gt;&gt;&gt;,这意味着网格有512 * 128个线程,每个内核都会在while循环中迭代(1024 * 1024)/(512 * 128)= 16次。 但只有14 * 48的SP,它说,只有14 * 48线程可以同时运行无论多少块数或线程数配置中的,有什么的blocknum和threadNum点在配置,为什么不只是data
。
<<<number of SMs, number of SPs>>>
和<<<128, 512>>>
之间是否有任何区别,也许前者会循环迭代16次,循环和字母32次,但前者有两个块来安排。有没有办法知道什么是最好的配置,不只是比较结果和选择最好的,因为我们无法尝试每一个组合,所以结果不是最完整,但最好的尝试。
我们知道只有一个块可以运行SM一次,但是CUDA在哪里存储其他块的上下文,假设512个块和14个SM,只有14个块在SM中有它们的上下文,那么另一个498块的背景?
答案 0 :(得分:2)
我们也知道该块对应于SM,而线程对应于SP
这是不正确的。 SM可以同时处理多个块,SP可以同时处理多个线程。
1)我认为您的问题可能是由于不将应用程序需要完成的工作与可用于完成该工作的资源分开。启动内核时,指定要完成的工作。然后,GPU使用其资源来执行工作。 GPU拥有的资源越多,它可以并行完成的工作就越多。任何不能并行完成的工作都是连续完成的。
通过让程序员指定需要完成的工作而不将其与给定GPU上可用的资源量相关联,CUDA提供了一个抽象,允许应用程序无缝扩展到任何GPU。
但是只有14 * 48个SP,这表示无论您的配置中有多少块编号或线程编号,只能同时运行14 * 48个线程
SP是流水线的,因此它们可以同时处理多个线程。每个线程都处于不同的完成阶段。每个SP可以启动一个操作并产生每个时钟一个操作的结果。但是,正如您现在所看到的,即使您的陈述是正确的,也不会导致您的结论。
2)块中的线程可以使用共享内存相互协作。如果您的应用程序不使用共享内存,则块大小的唯一含义是性能。最初,您可以使用占用率计算器获得块大小的良好值。之后,您可以通过测试不同的尺寸来进一步微调块大小以提高性能。由于线程以32个为一组运行,称为warp,因此您希望块大小可被32整除。因此,要测试的块大小不是很多。
3)SM可以同时运行多个块。块的数量取决于每个块需要多少资源以及SM具有多少资源。块使用许多不同的资源,其中一个资源成为同时运行多少块的限制因素。占用计算器将告诉您限制因素是什么。
只有同时运行的块才会消耗SM上的资源。我认为这些资源就是你的意思。已完成的块和尚未启动的块不会占用SM上的资源。