【发布时间】:2020-08-06 06:45:54
【问题描述】:
似乎每个 SM 允许的最大驻留块数。但是,虽然很容易找到其他“硬”限制(例如,通过 `cudaGetDeviceProperties'),但似乎没有广泛记录驻留块的最大数量。
在下面的示例代码中,我将内核配置为每个块一个线程。为了检验这个 GPU(一个 P100)每个 SM 最多有 32 个常驻块的假设,我创建了一个 56*32 块的网格(56 = P100 上的 SM 数量)。每个内核需要 1 秒来处理(通过“睡眠”例程),所以如果我正确配置了内核,代码应该需要 1 秒。计时结果证实了这一点。配置 32*56+1 块需要 2 秒,建议每个 SM 32 个块是每个 SM 允许的最大值。
我想知道的是,为什么这个限制没有更广泛地使用?例如,它不显示“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
【问题讨论】:
-
@talonmies 谢谢 - 这是我第一次看到硬限制。我想知道为什么 Nvidia 不通过
cudaGetDeviceProperties提供这个号码。 -
因为它大多是无关紧要的。这就是为什么
-
仅供参考,从 CUDA 11 开始,此限制公开为
cudaDevAttrMaxBlocksPerMultiprocessor和cudaDeviceProp中的maxBlocksPerMultiProcessor。在此处查看最新文档:docs.nvidia.com/cuda/cuda-runtime-api/…。
标签: cuda