Мой вопрос: существуют ли условия гонки, когда несколько экземпляров ядра пытаются записать в один и тот же индекс буфера hiddenCounter
Ответ на этот вопрос решительно да, ваш код будет уязвим к условиям гонки, как написано в настоящее время.
Нужно ли принудительно устанавливать какую-либо синхронизацию?
Да, вы можете использовать для этой цели глобальная атомика . Все, кроме самых древних графических процессоров, будут поддерживать это. (все, что поддерживает OpenCL 1.2 или cl_khr_global_int32_base_atomics
и аналогичные расширения)
Обратите внимание, что это приведет к нетривиальным потерям производительности. В зависимости от ваших схем доступа и частоты, сбор промежуточных результатов в памяти private
или local
и запись их в глобальную память в конце ядра может быть быстрее. (В случае local
вся рабочая группа будет использовать только один глобальный атомарный вызов для каждой обновленной ячейки - вам нужно будет использовать локальную атомарность или алгоритм сокращения, чтобы накапливать значения из отдельных рабочих элементов по всей группе.)
Другой вариант - использовать гораздо больший буфер глобальной памяти со счетчиками для каждого рабочего элемента или группы. В этом случае вам не потребуется атомика для записи в них, но впоследствии вам нужно будет объединить значения на хосте. Очевидно, что он использует гораздо больше памяти и, вероятно, большую пропускную способность памяти - современные графические процессоры должны кэшировать доступ к вашему небольшому буферу hiddenCounter
. Так что вам нужно решить / попробовать, что является меньшим злом в вашем случае.