параллельное ядро ​​в OpenCL - PullRequest
0 голосов
/ 16 ноября 2018

Я хотел бы знать, как я могу запускать два или более разных ядра параллельно и одновременно?Очевидно, что в том же графическом процессоре используется OpenCL.Моя основная идея - использовать два разных ядра (ядро A и ядро ​​B), но им нужно использовать одну и ту же память (я не хочу дублировать память, используя один буфер для каждого в указателях «a» и «b»),Так есть ли другой способ выполнить двойное выполнение с помощью эффективного метода памяти?Коды ядер следующие: Ядро A:

_kernel  void kernelA(global struct VectorStruct* a, int aLen0, global struct VectorStruct* b, int bLen0, global struct VectorStruct* c, int cLen0) {
int i = get_local_id(0);
c[(i)].x = a[(i)].x + b[(i)].x; }

Ядро B:

_kernel  void kernelB(global struct VectorStruct* a, int aLen0, global struct VectorStruct* b, int bLen0, global struct VectorStruct* d, int cLen0){ int i = get_local_id(0); d[(i)].y = a[(i)].y + b[(i)].y; }

Определение для структуры VectorStruct следующее:

struct VectorStruct { int x; int y; };

В коде хоста мне нужно создать четыре указателя: VectorStruct * a VectorStruct * b VectorStruct * c VectorStruct * d Указатели «a» и «b» содержат данные, которые я передам в графический процессор.Указатель «c» будет хранить результаты ядра A, а указатель «d» будет хранить результаты ядра B.

1 Ответ

0 голосов
/ 16 ноября 2018

Вы можете поставить в очередь ваши 2 ядра с помощью clEnqueueNDRangeKernel() в параллельной очереди команд , то есть той, где CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE был передан во время clCreateCommandQueue. Затем передайте оба созданных объекта события в буфер чтения или вызова карты для считывания результата с хоста. Обратите внимание, что не все аппаратные средства и реализации OpenCL поддерживают одновременное выполнение различных ядер, поэтому в конечном итоге они могут быть до некоторой степени сериализованы.

Вы также можете добиться чего-то похожего с несколькими последовательными очередями команд.

Для вашего простого ядра может быть лучше использовать float2 для представления вашего вектора и выполнения векторизованного (SIMD) сложения в одном ядре. Компилятор OpenCL должен взять на себя векторные операции и автоматически распределить операции по параллельному оборудованию.

Для немного более сложных операций, где это не так хорошо работает, вы можете представить координаты x и y вектора в виде двухэлементного массива и просто поставить в два раза больше количества рабочих элементов в одном ядре, которое работает на чередующемся размеры.

Оба подхода дадут вам гораздо более эффективные схемы доступа к памяти.

Обратите внимание, что использование get_local_id(0) может быть ошибочным, в зависимости от того, чего вы хотите достичь - вы, вероятно, захотите использовать get_global_id(0) в этом случае.

...