Такая же программа OpenCL скомпилирована на разных устройствах OpenCL, возможно, на разных платформах. Для каждого устройства создается командная очередь. Так, например, могут быть две очереди, одна для CPU и одна для GPU.Использование различных команд командной строки OpenCL из нескольких потоков хоста
Можно ли вызвать clEnqueueNDRangeKernel
, а затем clEnqueueReadBuffer
(блокирование) в двух командных очередях с разных потоков хоста (по одному для каждой командной очереди)?
Например с помощью OpenMP, с петлей, как
// queues_ contains command queues for different contexts,
// each with one device on one platform (e.g. CPU and GPU)
#pragma omp parallel for num_threads(2) schedule(dynamic)
for(int i = 0; i < job_count; ++i) {
cl::CommandQueue& queue = queues_[omp_get_thread_num()];
// queue is for one device on one platform
// euqueue kernel, and read buffer on queue
}
это будет разделить список заданий на два куски для CPU и GPU. schedule(dynamic)
сделает так, чтобы планирование динамически адаптировалось к времени выполнения ядер. Хост-код будет тратить больше времени на ожидание ядра (в вызове блокировки clEnqueueReadBuffer
). Но благодаря процессору, процессор фактически будет занят выполнением ядра (в OpenCL) и в то же время ждет GPU для завершения (в главном коде).
На ваш вопрос, да. – Dithermaster
Я создал трассировщик лучей в реальном времени, который сбалансировал нагрузку между двумя GPUS и CPU. Я сделал это, создав поток для каждого устройства с собственным контекстом. Я использовал pthreads для этого (потому что в то время я не знал OpenMP), но я полагаю, что OpenMP будет работать так же хорошо. Я создал отдельный контекст, потому что в то время я не получал отдельные очереди с графическими процессорами Nvidia (OpenCL 1.1), а на форуме Nvidia кто-то из Nvidia рекомендовал создать другой контекст для каждого устройства, каждый со своим потоком. –