Есть привязки C ++ для OpenCL, вот пример с std :: vector .В примере 2 или 3 сценария использования (inputA, inputB, output).
Я не вижу привязок для stl :: list и не ожидаю этого из-за базовой структуры данных,std :: vector имеет постоянное выделение памяти для его буфера data()
, так что для ядра это просто кусок памяти.
STL vector data()
location может менять местоположение при добавлении элементов.Если в предварительно выделенном буфере недостаточно места, новый буфер перераспределяется с большим размером.Это вызовет проблемы, если вы обрабатываете вектор и пытаетесь добавить к нему элементы.Это когда вы «заблокируете» вектор, чтобы предотвратить модификацию во время обработки вашего ядра (или создать клон с использованием CoR).
Вектор STL может занять распределитель, пример содержит SVMAllocator.Это позволит вам использовать SVMUnMap для (предположительно) загрузки памяти на сервер (CoR).
Что касается структурирования вашей программы ... При приближении к многопоточности вы можете начать с определения ReadПисать роли.Кто производитель, кто потребитель?Это мультипроизводитель / один потребитель?Один производитель / мультипотребитель?Один производитель / один потребитель?
Как работают ваши ядра?Они только для чтения на входе и только для записи на выходе?Когда вы выполняете команду, загружается ли копия данных на сервер?
Как работают ваши производители?Они знают количество элементов, в которых они нуждаются заранее?Можете ли вы просто использовать один большой вектор и обеспечить небольшие куски?
Вы знакомы с дизайном Map / Reduce?Копирование при записи?Copy-On-читать?Одновременные буферы?Двойная буферизация?
Другое дело, что потоки не всегда должны работать всегда .Возможно signal
поток, чтобы начать работу, а затем дождаться его завершения (еще один сигнал "join"
).Во время этого кадра вы можете использовать подход с двойной буферизацией для получения данных в одном потоке и использования их в другом (т. Е. Загрузки команд).После "join"
вы можете поменять местами буферы.Когда каждый поток работает со своим собственным буферным фреймом, вам не нужны блокировки.Ваш буфер выглядит примерно так: { [input, output]:Frame, [input, output]:Frame }
, а вы просто меняете указатели { Frame*, Frame* }
.
Иногда существует также верхний предел количества потоков, которые вы можете эффективно использовать.Конечно, многоядерные процессоры расширяются, а графические процессоры имеют сотни «потоков», но если вы не понимаете, как потоки планируются и прерываются, больше не всегда лучше .Возьмем, к примеру, разницу в дизайне между Node.JS и Apache .
Я надеюсь, что это даст вам много возможностей для исследований / размышлений.Удачного кодирования!