Карта буфера OpenCL / unmap и enqueueWrite пропускная способность

У меня проблема с производительностью для моей оболочки opencl C ++, мне нужно как можно быстрее перенести данные из буфера d в ​​буфер b (используя map / unmap для достижения скорости DMA pci-e 6 ГБ / с), а затем скопировать эти данные в буфер a (при скорости устройства около 40 ГБ / с)

*********************************
*       device(discrete gpu)    *
*                               *
*     (enqueueCopyBuffer)       *
*   a <---->b                   *
*********************************
^
|(map/unmap)
|
***************
*   d------>c *
*  (memcpy)   *
*             *
*    host     *
*             *
***************

Я перепробовал много комбинаций ALLOC_HOST_PTR, COPY_HOST_PTR, … для a, b и c, но не смог найти оптимального решения.

Вот что я попробовал:

 d---->c (memcpy 10GB/s)
c----->b(map/unmap CL_ALLOC_HOST_PTR)(6GB/s) ,  b---->a (enqueueCopyBuffer ~5 GB/s)
(I think  ALLOC makes b host buffer)

d---->c (memcpy 10GB/s)
c------>b(map/unmap CL_READ_WRITE)(1.4GB/s) , b---->a (enqueueCopyBuffer 40GB/s)
(now b is device buffer but map/unmap is not good and buggy)

d------>a(enqueueWriteBuf CL_READ_WRITE)(1.7GB/s)
(I started the new project with this)
(multithreaded read/write does not go beyond 2GB/s)

но мне нужно:

 d----->c(memcpy 10GB/s)
c----->b(map/unmap CL_???_PTR)(6GB/s) ,  b---->a (enqueueCopyBuffer 40 GB/s)

Причина разделения a и b состоит в том, что для выполнения ядра необходимо использовать память устройства.

Причина разделения d и c заключается в том, что я реализую ускорение графического процессора в проекте с открытым исходным кодом, и я не хочу менять целостность массива проекта.

Есть по крайней мере дюжина из a, b, c, d, которые я должен использовать. 2 для скоростей, 1 для давления, …

Вопрос: Какую структуру буфера я должен реализовать, чтобы достичь цели «узкая часть не должна быть меньше 6 ГБ / с в любом месте». Должен ли я объединить все b вместе (то же самое для c) в больший буфер, чтобы сделать одно чтение / запись / отображение / удаление для всех них?

1

Решение

Ваше требование к фиксированной пропускной способности очень строго.

Если & b оба буфера на стороне устройства, мой совет использовать техника закрепленной памяти с простыми флагами выделения CL_MEM_READ_WRITE. Хотя лучшие результаты, которые я когда-либо достигал, составляли около 5,3 ГБ / с на PCIe 2.0 x16. Принимая во внимание, что передача памяти обычно происходит за микросекунды, вы можете сделать это с неблокирующей передачей памяти с ожиданием события на стороне хоста. Такое конвейерное выполнение задач обычно показывает хорошую пропускную способность.

Обычно (для a, b, c & d буферы), мой совет — использовать отдельную очередь команд для каждого типа трафика памяти, чтобы получить преимущества от передач DMA. Обычно достаточно 3 очереди команд — хост-устройство, устройство-устройство & Хост-узел.

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]