Практично ли писать в глобальный буфер без синхронизации с OpenCL? - PullRequest
0 голосов
/ 17 марта 2020

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

Я вычисляю вокселизацию от me sh, и для заполнения вокселей на внутренней стороне me sh не требуется. Это делает проблему проще.

Я надеюсь применить очень простой алгоритм, в котором ядро ​​просто вычисляет воксели, которые пересекают треугольник, и распределяет ядро ​​по каждому треугольнику me sh.

Моя текущая идея - просто заставить ядро ​​записать значение вокселей, которое оно вычисляет как пересекающее треугольник, без применения какой-либо синхронизации. Для меня не имеет значения количество треугольников, которых касается конкретный воксель, меня волнует только то, что я гарантирую идентификацию всех вокселей, которые касаются любого треугольника.

Таким образом, вопрос заключается в том, могу ли я ожидать, что этот простой подход «просто сработает», или существует ли возможное состояние гонки, при котором воксел, уже помеченный как занятый, может в конечном итоге очиститься?

Если проблема возможна, то разрешит ли атом хранилища c (и приведет к снижению производительности) проблему?

Ответы [ 2 ]

1 голос
/ 23 марта 2020

AFAICT, все, что написано в ответе номы, верно, кроме заключения. По идее это должно работать. На практике это, скорее всего, не сработает.

Проблема в том, что графические процессоры, как и процессоры, работают с памятью через кэши, а кэши имеют линии кэширования. Если вы просто хотите записать один байт, вся строка кэша по-прежнему выбирается, и вся строка кэша также сохраняется обратно . CU (вычислительные единицы) имеют свои отдельные кэши. Так что же произойдет, если вам не повезет, и два CU решат примерно в одно и то же время записать «1» в байты, которые находятся по другому адресу, но меньше, чем байты кэширования? оба CU извлекают одну и ту же кэш-строку из памяти (или L2), пишут «1» в правильном месте, а затем flu sh it. Но в памяти вы получите только одну «1» - в зависимости от того, какая строка кэша была очищена последней.

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

Я бы попытался найти эффективную реализацию параллельной таблицы ha sh на GPU.

1 голос
/ 22 марта 2020

Из спецификации OpenCL 1.2 :

3.3.1 Согласованность памяти

OpenCL использует модель памяти с расслабленной согласованностью; то есть состояние памяти, видимое для рабочего элемента, не гарантируется постоянным во всей коллекции рабочих элементов. В памяти рабочего элемента есть согласованность загрузки / хранения. Локальная память одинакова для всех рабочих элементов в одной рабочей группе на барьере рабочей группы. Глобальная память одинакова для всех рабочих элементов в одной рабочей группе на барьере рабочей группы, , но нет гарантий согласованности памяти между различными рабочими группами, выполняющими ядро ​​. В точке синхронизации обеспечивается согласованность памяти для объектов памяти, совместно используемых командами в очереди.

Поэтому, если каждый рабочий элемент обрабатывает один треугольник и обновляет значение вокселя любого вокселя, пересекающегося с этим треугольником, нет никакой гарантии для заказа грузов / складов из разных рабочих элементов (возможно в разных рабочих группах) для значений вокселей.

Таким образом, вопрос заключается в том, можно ли ожидать, что этот простой подход «просто сработает», или существует ли возможное состояние гонки, при котором воксел, уже помеченный как занятый, может в конечном итоге очиститься?

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

TL; DR: должно работать.

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