我需要float
在 OpenCL 的多个线程中添加一个相同的全局内存地址。对于任何两次模拟运行,结果永远不会相同,对atomic_add_f
函数的调用是此错误的根源。我正在使用带有驱动程序 436.02 的 Nvidia Titan Xp GPU。
由于 OpenCL 不支持atomic_add
with float
,因此可以使用以下方法atomic_cmpxchg
:
void atomic_add_f(volatile global float* addr, const float val) {
union {
uint u32;
float f32;
} next, expected, current;
current.f32 = *addr;
do {
next.f32 = (expected.f32=current.f32)+val; // ...*val for atomic_mul_f()
current.u32 = atomic_cmpxchg((volatile global uint*)addr, expected.u32, next.u32);
} while(current.u32!=expected.u32);
}
但是,此代码确实会产生不确定的结果。每次运行的结果略有不同,类似于出现竞态条件的情况。
我也试过这个版本
void atomic_add_f(volatile global float* addr, const float val) {
private float old, sum;
do {
old = *addr;
sum = old+val;
} while(atomic_cmpxchg((volatile global int*)addr, as_int(old), as_int(sum))!=as_int(old));
}
这也不能正常工作。这里提供的版本也不起作用。
这怎么可能以及如何解决?