OpenCL 3.0中float32类型atomic_fetch_add正确调用方法咨询
解决OpenCL 3.0浮点原子加法调用错误的方案
错误原因分析
- 扩展名称错误:你使用的
cl_ext_float_atomics并非NVIDIA设备支持的浮点原子扩展,GTX 2080这类NVIDIA GPU对应的浮点原子扩展是cl_nv_float_atomics,编译器识别不到错误的扩展名称,会忽略该指令,导致后续找不到浮点版本的原子函数。 - 类型转换与函数匹配问题:由于扩展未正确启用,编译器只能找到整数类型的
atomic_fetch_add实现,无法匹配atomic_float类型的参数,因此出现函数不匹配的错误。
正确的代码实现
针对NVIDIA GTX 2080(驱动515.x)及OpenCL 3.0环境,调整后的浮点原子加法实现如下:
#if __OPENCL_C_VERSION__ >= CL_VERSION_3_0 // NVIDIA设备启用浮点原子扩展 #pragma OPENCL EXTENSION cl_nv_float_atomics : enable // 直接传入float指针调用对应版本的atomic_fetch_add #define atomicadd(a, b) atomic_fetch_add((volatile __global float*)(a), (b)) #else // 旧版本兼容的hack实现 inline float atomicadd(volatile __global float* address, const float value) { float old = value, orig; while ((old = atomic_xchg(address, (orig = atomic_xchg(address, 0.0f)) + old)) != 0.0f); return orig; } #endif
补充说明
- 若要兼容不同厂商设备(如AMD),可同时判断厂商扩展:
#if __OPENCL_C_VERSION__ >= CL_VERSION_3_0 #if defined(__NV_CL_VERSION__) #pragma OPENCL EXTENSION cl_nv_float_atomics : enable #elif defined(__AMD_CL_VERSION__) #pragma OPENCL EXTENSION cl_amd_float_atomics : enable #endif #define atomicadd(a, b) atomic_fetch_add((volatile __global float*)(a), (b)) #else // 旧版本实现不变 inline float atomicadd(volatile __global float* address, const float value) { float old = value, orig; while ((old = atomic_xchg(address, (orig = atomic_xchg(address, 0.0f)) + old)) != 0.0f); return orig; } #endif - NVIDIA的
cl_nv_float_atomics扩展支持atomic_add(直接修改值,无返回)和atomic_fetch_add(返回旧值)两种浮点原子操作,可根据需求选择。
内容的提问来源于stack exchange,提问作者FangQ
相关产品推荐
相关产品推荐

