Распределение Dynami c в устройстве приводит к сбою копирования памяти - PullRequest
0 голосов
/ 18 июня 2020

Я использую API драйвера CUDA. Упрощенное описание проблемы выглядит следующим образом:

// файл .cu, скомпилировать в файл ptx.

extern "C" __global__ void SomeFunction(char* d_buffer) {
    float* p = malloc(sizeof(float) * 100); // Allocate memory per thread
    do some calculation with allocated memory. // About 5x10^5 threads.
    do some other calculation with d_buffer.
    free(p)
}

//. cpp file

int main()
{   // Allocate device buffer
    CUdeviceptr d_buffer;
    cuMemAlloc(&d_buffer, bytes);
    // Allocate host buffer 
    char* h_buffer = new char(bytes); 
    // copy host buffer to device buffer 
    cuMemcpyHtoD(h_buffer, d_buffer, bytes);

    CUfunction func;
    cuModuleGetFunction(&func, module, "SomeFunction");
    cuLaunchKernel(func, grid_dims,...,block_dims,...,args,...);
    // copy device buffer to host buffer 
    cuMemcpyDtoH(d_buffer, h_buffer, bytes); // Failed! 
}

Проблема заключается в операции копирования в последней строке файла. cpp FAILED. Однако, если я закомментировал выделение динамического c (mallo c, бесплатно) в файле .cu, операция копирования будет УСПЕШНОЙ. Мой вопрос в том, есть ли какие-либо ограничения на использование динамического c выделения в API драйвера? Если да, то что это? Как правильно использовать динамическое выделение c в API драйвера?

1 Ответ

2 голосов
/ 18 июня 2020

Мой вопрос в том, есть ли какие-либо ограничения с использованием динамического c выделения в API драйвера?

Не более чем в API времени выполнения.

Как я могу правильно использовать динамическое выделение c в API драйвера?

Важно понимать, что копия после ядра дает сбой, потому что само ядро ​​выдает ошибки во время выполнения.

Как описано в руководстве по программированию , распределение ядра времени выполнения происходит из кучи фиксированного размера, значение по умолчанию - 8 МБ. Если вы исчерпаете эту кучу, вызовы malloc в ядре завершатся ошибкой, и вызов вернет NULL. Это условие, которое вы можете проверить. Я предполагаю, что вы этого не сделаете, а затем ваш «выполнить некоторые вычисления с выделенной памятью» разыменует нулевой указатель и взорвется.

Чтобы исправить это в API драйвера, вам нужно будет вызвать cuCtxSetLimit с параметром CU_LIMIT_MALLOC_HEAP_SIZE и установите для этого размера кучи что-то более реалистичное c (подумайте, что максимальное количество резидентных потоков на вашем устройстве x количество байтов на поток, округленное до ближайшего выравнивания страницы 16 байтов, плюс запас прочности ). Если вы это сделаете, все, вероятно, заработает.

...