У меня есть этот код:
__global__ void testCuda() {}
void wrapperLock()
{
std::lock_guard<std::mutex> lock(mutexCudaExecution);
// changing this value to 20000 does NOT trigger "Segmentation fault"
usleep(5000);
runCuda();
}
void runCuda()
{
testCuda<<<1, 1>>>();
cudaDeviceSynchronize();
}
Когда эти функции выполняются из примерно 20 потоков, я получаю Segmentation fault
. Как написано в комментарии, изменение значения в usleep()
до 20000 отлично работает.
Есть ли проблема с CUDA и потоками?
Мне кажется, что CUDA нужно немного времени, чтобы восстановиться, когда выполнение закончилось, даже когда ему нечего было делать.
ОБНОВИТЬ:
Согласно http://docs.nvidia.com/cuda/cuda-c-programming-guide/#um-gpu-exclusive проблема заключалась в одновременном доступе к унифицированной памяти, которую я использую. Мне пришлось обернуть вызовы ядра CUDA и получить доступ к Unified Memory с помощью std::lock_guard
и теперь программа работает без проблем в течение 4 дней при загрузке тяжелых потоков.
Я должен вызвать в каждом потоке, как это было предложено Marco & Robert - cudaSetDevice
иначе он снова cudaSetDevice
.
Используя один контекст CUDA, несколько потоков хоста должны либо делегировать свою работу CUDA потоку контекст-владельца (аналогично рабочему потоку), либо связывать контекст с cuCtxSetCurrent (API-интерфейс драйвера) или cudaSetDevice, чтобы не перезаписывать контекстные ресурсы.