распределение памяти внутри ядра CUDA - PullRequest
6 голосов
/ 21 марта 2012

У меня есть следующий (фрагмент) ядра.

__global__ void plain(int* geneVec, float* probs, int* nComponents, float* randomNumbers,int *nGenes)
{

    int xid = threadIdx.x + (blockDim.x * blockIdx.x);

    float* currentProbs= (float*)malloc(sizeof(float)*tmp);

         .....
         .....

    currentProbs[0] = probs[start];
    for (k=1;k<nComponents[0]; k++)
    {
        currentProbs[k] = currentProbs[k-1] + prob;
    }

       ...
       ...
      free(currentProbs);

}

Когда он статичен (даже при тех же размерах), он очень быстрый, но при динамическом распределении CurrentProbs (как указано выше) производительность ужасна.

В этом вопросе говорилось, что я могу сделать это внутри ядра: CUDA выделяет память в функции __device__

Вот связанный вопрос: Эффективность функции Malloc в CUDA

Мне было интересно, решали ли это какие-либо другие методы, кроме предложенного в статье? Кажется смешным, что в ядре нельзя использовать malloc / free без такого наказания.

1 Ответ

8 голосов
/ 21 марта 2012

Я думаю, что причина того, что введение malloc () замедляет ваш код, заключается в том, что он выделяет память в глобальной памяти.Когда вы используете массив фиксированного размера, компилятор, скорее всего, поместит его в файл реестра, что гораздо быстрее.

Необходимость выполнения malloc внутри вашего ядра может означать, что вы пытаетесь сделать слишком многоработать с одним ядром.Если каждый поток выделяет разный объем памяти, то каждый поток выполняется в цикле for разное количество раз, и вы получаете много расхождений деформации.

Если каждый поток в деформациях запускает циклы одинакового числараз, просто выделить заранее.Даже если они запускаются разное количество раз, вы можете использовать постоянный размер.Но вместо этого, я думаю, вы должны посмотреть, как вы можете реорганизовать свой код, чтобы полностью удалить этот цикл из вашего ядра.

...