Странное поведение операции атомарного добавления OpenCL

Для проекта мне пришлось погрузиться в OpenCL: дела идут довольно хорошо, за исключением того, что теперь мне нужны атомарные операции. Я выполняю код OpenCL поверх графического процессора Nvidia с последними драйверами. clGetDeviceInfo() запрос CL_DEVICE_VERSION возвращает мне: OpenCL 1.0 CUDA, поэтому я думаю, что мне нужно обратиться к спецификациям OpenCL 1.0.

Я начал использовать операцию atom_add в своем ядре с буфером __global int* vnumber: atom_add(&vnumber[0], 1);. Это дало мне явно неправильные результаты. Таким образом, в качестве дополнительной проверки я переместил инструкцию добавления в начало ядра, чтобы она выполнялась для каждого потока. Когда ядро ​​запускается с потоками 512 x 512, содержимое vnumber[0] равно: 524288, что равно 2 x 512 x 512, что в два раза превышает значение, которое я должен получить. Самое смешное, что при изменении операции добавления на atom_add(&vnumber[0], 2); возвращаемое значение равно 65536, опять же в два раза больше, чем я должен получить.

Кто-то уже сталкивался с чем-то подобным? Я упускаю что-то очень простое? Я проверил правильность типов данных, но все в порядке (я использую буфер *int и выделяю его с помощью sizeof(cl_int)).


person Neenster    schedule 02.11.2011    source источник


Ответы (1)


Вы используете atom_add, расширение OpenCL 1.0 для локальной памяти. Тем не менее, вы передаете ему глобальную память. Вместо этого попробуйте atomic_add из OpenCL 1.1, который работает с глобальной памятью.

person vocaro    schedule 02.11.2011
comment
Запрос моего CL_DEVICE_VERSION возвращает OpenCL 1.0, поэтому я имею в виду следующие спецификации: ссылка. Atomic реализованы как расширение, мой GPU поддерживает расширение cl_khr_global_int32_base_atomics, поэтому я думаю, что могу использовать atomics только в глобальных буферах памяти. Или, по крайней мере, еще и глобальную память. Кроме того, могу ли я использовать инструкцию atomic_add, если кажется, что поддерживается только версия 1.0? - person Neenster; 03.11.2011
comment
Разница между atom_add и atomic_add НЕ в том, что они работают с глобальной памятью. Есть cl_khr_(глобальный или локальный)_int(размер)_(базовый или расширенный)_atomics, а есть встроенные. Вам нужно будет включить глобальную и/или локальную версию для того, что вам нужно. Atom_* являются расширениями, а atomic_ являются встроенными, а также требуют, чтобы указатель был изменчивым. - person arsenm; 04.11.2011