OpenCL clEnqueueNDRangeKernel блокирует дальнейшее выполнение хоста - PullRequest
0 голосов
/ 15 февраля 2019

Насколько я понимаю, вы сможете отправить несколько ядер (заданий) в очередь команд, а затем дождаться их завершения.Однако, похоже, что это не так для меня.Каждый раз, когда я вызываю clEnqueueNDRangeKernel с графическим процессором в качестве устройства, вызов функции clEnqueueNDRangeKernel блокирует дальнейшее выполнение на хосте (CPU).Реализация работает так, как задумано, с процессором в качестве устройства, поэтому проблема возникает только тогда, когда ядро ​​работает на GPU.Ядро - это просто фиктивное ядро, выполняющее некоторые add и mult для частных переменных и без аргументов.Я пробовал два разных ноутбука с одинаковыми результатами: один с процессором Intel i5 (4-го поколения) и графическим процессором Nvidia (Geforce 840M), а другой с Intel i5 (8-го поколения) и встроенным графическим процессором.

Следующий вывод может помочь вам понять проблему, когда ЦП выдает ожидаемый вывод: «Время в clEnqueueNDRangeKernel» намного меньше, чем «Время завершения двух ядер».

Исполнительное устройство как
GPU:
Время (сек) в clEnqueueNDRangeKernel: 13.6459
Время (сек) в clEnqueueNDRangeKernel: 13.6244
Время (сек) для завершения двух ядер: 27.2704
Процессор:
Время (сек) в clEnqueueNDRangeKernel: 4.205e-05
Время (сек) в clEnqueueNDRangeKernel: 6.732e-06
Время (сек) для завершения двух ядер: 0.727572

Код:

...
Profiler timer1;
timer1.ResetTime();
Profiler timer2;
timer2.ResetTime();
err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, global, NULL, 0, NULL, NULL);
checkError(err, "Enqueueing kernel");

std::cout << "Time (sec) in clEnqueueNDRangeKernel: " << timer2.GetTime() << std::endl;
timer2.ResetTime();

err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, global, NULL, 0, NULL, NULL);
checkError(err, "Enqueueing kernel");

std::cout << "Time (sec) in clEnqueueNDRangeKernel: " << timer2.GetTime() << std::endl;

err = clFinish(commands);
checkError(err, "Finish command queue");

std::cout << "Time (sec) to finish two kernels: " << timer1.GetTime() << std::endl;

Спасибо, что уделили время!

...