Как правильно реализовать стек в OpenCL 1.2? - PullRequest
0 голосов
/ 24 мая 2018

Вопрос

Предположим, несколько рабочих элементов хотят добавить в глобальный стек:

void kernel(__global int* stack) {
    ... do stuff ...
    push(stack, value);
    ... do stuff ...
    return y;
}

Желательно, чтобы после запуска ядра stack содержал каждое valueподтолкнул к этому.Заказ не имеет значения.Как правильно сделать это в OpenCL 1.2?

Что я пробовал

Очевидная идея - использовать atomic_inc, чтобы получить длину и просто написать в нее:

void push(__global int* stack, int val) {
    int idx = atomic_inc(stack) + 1; // first element is the stack length
    stack[idx] = val;
}

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

void push(__global int* stack, int val) {
    stack[get_global_id(0)] = val;
}

Это оставило бы нас с редким массивом значений:

[0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 9, 0, 0, ...]

Который затем может быть сжат с помощью «потоковое сжатие» .Поэтому мне интересно, какая из этих идей наиболее эффективна, и, возможно, есть третий вариант, о котором я не знаю.

1 Ответ

0 голосов
/ 24 мая 2018

Я не могу дать вам однозначный ответ здесь, но я могу сделать несколько предложений, чтобы попробовать - если у вас есть ресурсы, попробуйте реализовать более одного из них и профилировать их производительность на всех различных типах.Реализация OpenCL, которую вы планируете развернуть.Вы можете обнаружить, что разные решения работают по-разному на разных аппаратных / программных средствах.

  1. Создайте стек для каждой рабочей группы в локальной памяти (либо явно, либо путем сжатия после того, как все значения были сгенерированы) и только увеличивайтеглобальный стек по количеству рабочих групп и скопировать весь локальный стек в глобальный.Это означает, что у вас есть только одно глобальное атомарное добавление на рабочую группу.Конечно, лучше работает для больших групп.
  2. Ваш самый большой источник атомных разногласий в наивном подходе будет из предметов в одной рабочей группе.Таким образом, вы можете создать столько стеков, сколько элементов в рабочей группе, и каждый элемент в группе должен быть представлен в своем «собственном» стеке.После этого вам все еще понадобится этап уплотнения, чтобы объединить все это в один список.Измените размер группы, если вы попробуете это.Я не уверен, в какой степени текущие графические процессоры страдают от ложного совместного использования (атомика блокирует всю строку кэша, а не только это слово), поэтому вы захотите проверить это и / или поэкспериментировать с различными промежутками между счетчиками стека в памяти.
  3. Записывает все результаты в фиксированные смещения (на основе глобального идентификатора) в массив, достаточно большой, чтобы уловить наихудший случай, и ставит в очередь отдельное ядро ​​сжатия, которое обрабатывает результат в непрерывный массив.
  4. Донне утруждайте себя компактным представлением результата.Вместо этого используйте разреженный массив в качестве входных данных для следующего этапа вычислений.Рабочая группа следующего этапа может сжать фиксированное подмножество разреженного массива в локальную память.Когда это сделано, каждый рабочий элемент затем работает с одним элементом сжатого массива.Итерируйте внутри ядра, пока все не будет обработано.Насколько хорошо это работает, будет зависеть от того, насколько предсказуемо статистическое распределение разреженных элементов в массиве, а также от выбранного вами размера рабочей группы и от того, какой объем разреженного массива обрабатывает каждая рабочая группа.Эта версия также исключает возможность обращения к главному процессору.
  5. В частности, на Intel IGP я слышал, что геометрические шейдеры DirectX / OpenGL / Vulkan с переменным числом выходов работают исключительно хорошо.Если вы можете написать свой алгоритм в формате геометрического шейдера, возможно, стоит попробовать, если вы ориентируетесь на эти устройства.Для nvidia / AMD не беспокойтесь об этом.

Возможно, есть и другие варианты, но они должны дать вам некоторые идеи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...