Cuda 每个SM的最大常驻区块数?
似乎每个SM都有一个允许的最大驻留块数。但是,尽管很容易找到其他“硬”限制(例如,通过“cudaGetDeviceProperties”),但似乎没有广泛记录驻留块的最大数量 在下面的示例代码中,我将内核配置为每个块一个线程。为了验证这个GPU(P100)每个SM最多有32个驻留块的假设,我创建了一个56*32块的网格(56=P100上的SMs数量)。每个内核需要1秒的处理时间(通过“睡眠”例程),因此如果我正确配置了内核,代码应该需要1秒。计时结果证实了这一点。配置32*56+1个块需要2秒钟,这表明每个SM允许的32个块是每个SM允许的最大值 我想知道的是,为什么不更广泛地使用这个限制?例如,它不会显示“cudaGetDeviceProperties”。在哪里可以找到各种GPU的此限制?或者这不是一个真正的极限,而是从其他硬极限衍生出来的 我正在运行CUDA 10.1Cuda 每个SM的最大常驻区块数?,cuda,Cuda,似乎每个SM都有一个允许的最大驻留块数。但是,尽管很容易找到其他“硬”限制(例如,通过“cudaGetDeviceProperties”),但似乎没有广泛记录驻留块的最大数量 在下面的示例代码中,我将内核配置为每个块一个线程。为了验证这个GPU(P100)每个SM最多有32个驻留块的假设,我创建了一个56*32块的网格(56=P100上的SMs数量)。每个内核需要1秒的处理时间(通过“睡眠”例程),因此如果我正确配置了内核,代码应该需要1秒。计时结果证实了这一点。配置32*56+1个块需要2秒钟
#include <stdio.h>
#include <sys/time.h>
double cpuSecond() {
struct timeval tp;
gettimeofday(&tp,NULL);
return (double) tp.tv_sec + (double)tp.tv_usec*1e-6;
}
#define CLOCK_RATE 1328500 /* Modify from below */
__device__ void sleep(float t) {
clock_t t0 = clock64();
clock_t t1 = t0;
while ((t1 - t0)/(CLOCK_RATE*1000.0f) < t)
t1 = clock64();
}
__global__ void mykernel() {
sleep(1.0);
}
int main(int argc, char* argv[]) {
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, 0);
int mp = prop.multiProcessorCount;
//clock_t clock_rate = prop.clockRate;
int num_blocks = atoi(argv[1]);
dim3 block(1);
dim3 grid(num_blocks); /* N blocks */
double start = cpuSecond();
mykernel<<<grid,block>>>();
cudaDeviceSynchronize();
double etime = cpuSecond() - start;
printf("mp %10d\n",mp);
printf("blocks/SM %10.2f\n",num_blocks/((double)mp));
printf("time %10.2f\n",etime);
cudaDeviceReset();
}
是的,每个SM的块数有限制。SM中可包含的最大块数是指给定时间内活动块的最大数量。块可以组织成一维或二维网格,每个维度最多有65535个块,但gpu的SM只能容纳一定数量的块。这个限制与Gpu的计算能力有两种联系 CUDA规定的硬件限制。 每个gpu允许每个SM的最大块数限制,而不考虑它包含的线程数和使用的资源量。例如,计算能力为2.0的Gpu限制为8块/平方米,而计算能力为7.0的Gpu限制为32块/平方米。这是您可以实现的每个SM的最佳活动块数:我们称之为MAX_块 从每个块使用的资源量派生的限制。 一个块由线程组成,每个线程使用一定数量的寄存器:它使用的寄存器越多,包含它的块使用的资源数量就越多。类似地,分配给块的共享内存量增加了块需要分配的资源量。一旦超过某个值,一个块所需的资源数量将非常大,SM将无法分配MAX_块所允许的数量:这意味着每个块所需的资源量限制了每个SM的最大活动块数量 如何找到这些边界? 库达也想到了这一点。在他们的网站上,您可以通过该网站发现按计算能力分组的硬件限制。您还可以输入块使用的资源量(线程数、每个线程的寄存器数、共享内存字节数),并获取有关活动块数的图形和重要信息。 链接文件的第一个选项卡允许您根据使用的资源计算SM的实际使用情况。如果您想知道每个线程使用多少个寄存器,那么必须添加-Xptxas-v选项,让编译器在创建PTX时告诉您它使用了多少个寄存器。
在文件的最后一个选项卡中,您将找到按计算能力分组的硬件限制 @talonmies谢谢-这是我第一次看到硬限制。我想知道Nvidia为什么不通过
cudaGetDeviceProperties
提供这个号码,因为它基本上是不相关的。这就是为什么从CUDA 11开始,该限制在CUDADEVATTRMAXBLOCKSPERMULTIPROP
中显示为CUDADEVATTRMAXBLOCKPERMULTIPROPER
,在cudaDeviceProp
中显示为MaxBlockPERMULTIPROPER
。请参阅此处的最新文档:。我知道有许多因素限制了块的数量。我问了更多关于硬限制的问题,这似乎并没有被广泛记录(尽管上面的链接表明存在限制)。
% srun -p gpuq sm_short 1792
mp 56
blocks/SM 32.00
time 1.16
% srun -p gpuq sm_short 1793
mp 56
blocks/SM 32.02
time 2.16
% srun -p gpuq sm_short 3584
mp 56
blocks/SM 64.00
time 2.16
% srun -p gpuq sm_short 3585
mp 56
blocks/SM 64.02
time 3.16