выделение памяти внутри ядра CUDA

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

__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 _ _ function

вот вопросы: эффективность функции Malloc в CUDA

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

1 ответов


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

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

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