每个SM的最大驻留块数?

时间:2020-04-23 03:23:24

标签: cuda

似乎每个SM允许有最大数量的驻留块。但是,尽管很容易找到其他“硬”限制(例如,通过`cudaGetDeviceProperties'),但似乎并未广泛记录驻留块的最大数量。

在以下示例代码中,我将内核配置为每个块一个线程。为了测试该GPU(一个P100)每个SM最多具有32个驻留块的假设,我创建了一个56 * 32块的网格(56 = P100上的SM数量)。每个内核需要1秒的处理时间(通过“睡眠”例程),因此,如果我已正确配置内核,则代码应花费1秒的时间。计时结果证实了这一点。使用32 * 56 + 1块进行配置需要2秒钟,建议每个SM最多32个块。

我想知道的是,为什么没有更广泛地使用此限制?例如,它不会显示“ cudaGetDeviceProperties”。在哪里可以找到各种GPU的限制?也许这不是一个真正的限制,而是源自其他硬性限制?

我正在运行CUDA 10.1

#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();
}

结果:

% 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

1 个答案:

答案 0 :(得分:1)

是的,每个SM的块数有限制。 SM中可以包含的最大块数是指给定时间内活动块的最大数。可以将块组织为一维或二维网格,每个维度最多可以包含65,535个块,但是您的GPU的SM将只能容纳一定数量的块。此限制通过两种方式与您的Gpu的计算能力相关联。

CUDA规定的硬件限制。

每个gpu允许每个SM的最大块数限制,而不管其包含的线程数和使用的资源量如何。例如,具有计算能力2.0的Gpu的限制为8个块/ SM,而具有计算能力7.0的Gpu的限制为32个块/ SM。这是可以实现的每个SM的最佳活动块数:我们将其称为MAX_BLOCKS。

从每个块使用的资源量得出的限制。

一个块是由线程组成的,每个线程使用一定数量的寄存器:它使用的寄存器越多,包含它的块所使用的资源就越多。类似地,分配给一个块的共享内存量会增加该块需要分配的资源量。一旦超过某个值,一个块所需的资源数量将很大,以至于SM将无法分配MAX_BLOCKS所允许的数量的块:这意味着每个块所需的资源量是有限的每个SM的最大活动块数。

如何找到这些边界?

CUDA也考虑过这一点。在Cuda Occupancy Calculator file上可以找到他们的站点,通过它们您可以发现按计算能力分组的硬件限制。您还可以输入块使用的资源量(线程数,每个线程的寄存器,共享内存的字节数),并获取有关活动块数的图形和重要信息。 链接文件的第一个选项卡使您可以根据使用的资源来计算SM的实际使用情况。如果您想知道每个线程使用了多少个寄存器,则必须添加-Xptxas -v选项,以使编译器在创建PTX时告诉您正在使用的寄存器数。 在文件的最后一个选项卡中,您将找到按计算功能分组的硬件限制。

相关问题