2017-01-24 3 views
1

Такая же программа 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 для завершения (в главном коде).

+2

На ваш вопрос, да. – Dithermaster

+1

Я создал трассировщик лучей в реальном времени, который сбалансировал нагрузку между двумя GPUS и CPU. Я сделал это, создав поток для каждого устройства с собственным контекстом. Я использовал pthreads для этого (потому что в то время я не знал OpenMP), но я полагаю, что OpenMP будет работать так же хорошо. Я создал отдельный контекст, потому что в то время я не получал отдельные очереди с графическими процессорами Nvidia (OpenCL 1.1), а на форуме Nvidia кто-то из Nvidia рекомендовал создать другой контекст для каждого устройства, каждый со своим потоком. –

ответ

1

Если контексты разные, то они работают независимо, даже с 3D-приложениями. В зависимости от реализации два контекста могут быть вытеснены или сверхпроницаемы драйверами, но вы можете дополнительно добавить синхронизацию на основе событий между контекстами, чтобы один элемент в очереди-a ожидал завершения элемента в очереди-b.

Если они живут в одном контексте, вы можете выполнять неявную синхронизацию между двумя очередями с помощью драйверов или манипуляций с apis.

Использование всех ядер процессора для связанного с памятью ядра не позволяет ему копировать массив в и из gpu достаточно быстро, если вы не используете прямой доступ к памяти. Когда вы копируете, который устанавливает cpu без копирования. Если кеш большой и достаточно быстрый, возможно, он не нуждается в такой вещи.

Смежные вопросы