2013-11-11 7 views
0

У меня есть ядро ​​OpenCL, и я хочу запустить его на всех обнаруженных устройствах с поддержкой OpenCL (как и все доступные графические процессоры) в разных системах, я был бы благодарен за знание, есть ли простой метод , Я имею в виду создание единой очереди команд для всех устройств.Запуск ядра OpenCL на нескольких графических процессорах

Заранее спасибо:]

+2

Создайте отдельные контексты для каждого устройства и выполните их в отдельных потоках (например, с помощью pthreads). –

ответ

3

Вы не можете создать единую очередь команд для всех устройств; заданная командная очередь привязана к одному устройству. Тем не менее, вы можете создать отдельные очереди команд для каждого устройства OpenCL и подать их на работу, которые должны выполняться одновременно.

2

Как указывает Dithermaster, вы сначала создаете отдельную очередь команд для каждого устройства, например, у вас может быть несколько графических процессоров. Вы можете поместить их в массив, например, здесь является указателем на массив, который вы можете настроить:

cl_command_queue* commandQueues; 

Однако в моем опыте он не всегда был «слэм-данк» в получении различных команду очереди, выполняемые одновременно, как можно проверить с помощью информации о времени события (проверка на перекрытие), которую вы можете получить через свое профилирование или используя сторонние инструменты профилирования. Вы должны сделать этот шаг в любом случае, чтобы проверить, что работает или не работает в вашей настройке.

Альтернативный подход, который может работать достаточно хорошо, чтобы использовать OpenMP для выполнения очереди команд одновременно, например, вы делаете что-то вроде:

#pragma omp parallel for default(shared) 
    for (int i = 0; i < numDevices; ++i) { 
      someOpenCLFunction(commandQueues[i], ....); 
    } 
2

Предположим, у вас есть N устройств, а также в 100 элементов работы (рабочие места). Что вы должны сделать, это примерно так:

#define SIZE 3 

std::vector<cl::Commandqueue> queues(SIZE); //One queue for each device (same context) 
std::vector<cl::Kernel> kernels(SIZE); //One kernel for each device (same context) 
std::vector<cl::Buffer> buf_in(SIZE), buf_out(SIZE); //One buffer set for each device (same context) 

// Initialize the queues, kernels, buffers etc.... 
//Create the kernel, buffers and queues, then set the kernel[0] args to point to buf_in[0] and buf_out[0], and so on... 

// Create the events in a finished state 
std::vector<cl::Event> events; 
cl::UserEvent ev; ev.setStatus(CL_COMPLETE); 
for(int i=0; i<queues.size(); i++) 
    events.push_back(ev); 

//Run all the elements (a "first empty, first run" scheduler) 
for(int i=0; i<jobs.size(); i++){ 
    bool found = false; 
    int x = -1; 
    //Try all the queues 
    while(!found){ 
     for(int j=0; j<queue.size(); j++) 
      if(events[j].getInfo<CL_EVENT_COMMAND_ EXECUTION_STATUS>() == CL_COMPLETED){ 
       found = true; 
       x = j; 
       break; 
      } 
     if(!found) Sleep(50); //Sleep a while if not all the queues have completed, other options are possible (like asigning the job to a random one) 
    } 
    //Run it 
    events[x] = cl::Event(); //Clean it 
    queues[x].enqueueWriteBuffer(...); //Copy buf_in 
    queues[x].enqueueNDRangeKernel(kernel[x], ....); //Launch the kernel 
    queues[x].enqueueReadBuffer(... , events[x]); //Read buf_out 
} 

//Wait for completion 
for(int i=0; i<queues.size(); i++) 
    queue[i].Finish(); 
+0

Что делать, если для работы с одним ядром требуется многоуровневое устройство? Будут ли буферисты неявно распределены между устройствами (скопировано неявно), так что мне вообще нужны разные контексты для разных устройств? Или нет неявных копий, а буфер имеет экземпляры на всех устройствах и изменен независимо? –

+0

Я допускаю такой же контекст для всего приложения, это означает, что буферы автоматически копируются между устройствами, когда это необходимо. Для каждого конвейера (устройства) вам нужно одно ядро ​​+ очередь + буферы. – DarkZeros

+0

, так что если мне нужен такой же алгоритм сортировки, мне нужно скомпилировать для каждого устройства? Спасибо. –

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