Максимальное количество резидентных блоков на SM? - PullRequest
0 голосов
/ 23 апреля 2020

Похоже, что максимально допустимое количество резидентных блоков на SM. Но в то время как другие «жесткие» ограничения легко найти (например, через «cudaGetDeviceProperties»), максимальное количество резидентных блоков, похоже, не документировано широко.

В следующем примере кода я настраиваю ядро ​​с одним потоком на блок. Чтобы проверить гипотезу о том, что этот графический процессор (P100) имеет максимум 32 резидентных блока на SM, я создаю сетку из 56 * 32 блоков (56 = количество SM на P100). Каждому ядру требуется 1 секунда для обработки (с помощью процедуры «сна»), поэтому, если я правильно настроил ядро, код должен занять 1 секунду. Результаты сроков подтверждают это. Конфигурирование с 32 * 56 + 1 блоками занимает 2 секунды, предполагая, что 32 блока на SM являются максимально допустимыми для SM.

Интересно, почему этот предел не стал более доступным? Например, он не отображается `cudaGetDeviceProperties '. Где я могу найти этот предел для разных графических процессоров? Или, может быть, это не реальный предел, а вытекает из других жестких ограничений?

Я использую 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 Ответ

1 голос
/ 23 апреля 2020

Да, существует ограничение на количество блоков на SM. Максимальное количество блоков, которое может содержаться в SM, относится к максимальному количеству активных блоков в данный момент времени. Блоки могут быть организованы в одно- или двумерные сетки по 65 535 блоков в каждом измерении, но SM вашего графического процессора сможет вместить только определенное количество блоков. Этот предел связан двумя способами с возможностями вычислений вашего графического процессора.

Аппаратный предел, установленный CUDA.

Каждый графический процессор допускает максимальный предел блоков на SM, независимо от количества потоков, которые он содержит, и количества используемых ресурсов. Например, для графического процессора с вычислительной способностью 2.0 установлено ограничение в 8 блоков / SM, а для графического процессора с вычислительной возможностью 7.0 - 32 блока / SM. Это лучшее количество активных блоков для каждого SM, которое вы можете достичь: назовем его MAX_BLOCKS.

Предел, полученный из количества ресурсов, используемых каждым блоком.

Блок состоит из потоков, и каждый поток использует определенное количество регистров: чем больше регистров он использует, тем больше количество ресурсов, используемых блоком, который его содержит. Точно так же объем совместно используемой памяти, назначенной блоку, увеличивает количество ресурсов, которые блок должен быть выделен. Как только определенное значение превышено, количество ресурсов, необходимых для блока, будет настолько большим, что SM не сможет выделить столько блоков, сколько это разрешено MAX_BLOCKS: это означает, что количество ресурсов, необходимых для каждого блока, ограничено максимальное количество активных блоков для каждого SM.

Как мне найти эти границы?

CUDA тоже подумала об этом. На их сайте доступен файл Cuda Occupancy Calculator, с помощью которого вы можете узнать аппаратные ограничения, сгруппированные по вычислительным возможностям. Вы также можете ввести количество ресурсов, используемых вашими блоками (количество потоков, регистров на потоки, байт общей памяти) и получить графики и важную информацию о количестве активных блоков. Первая вкладка связанного файла позволяет рассчитать фактическое использование SM на основе используемых ресурсов. Если вы хотите узнать, сколько регистров в каждом потоке вы используете, вам нужно добавить опцию -Xptxas -v, чтобы компилятор сообщал вам, сколько регистров он использует при создании PTX. На последней вкладке файла вы найдете аппаратные ограничения, сгруппированные по возможностям вычислений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...