在OpenCL中实现浮点数的原子加法运算(atomic add for floating point in OpenCL)

今天在OpenCL的开发过程中遇到了对浮点数的原子运算(atomic operations)的问题。OpenCL spec中只提供了对于32位或64位整数的原子运算;对于浮点数,我们就得另辟蹊径了。

因为OpenCL在语法上跟CUDA非常类似,我们可以参考一下CUDA C Programming Guide 上面关于浮点数原子加法的例子,如下:

__device__ double atomicAdd(double* address, double val)
{
  unsigned long long int* address_as_ull = (unsigned long long int*)address;
  unsigned long long int old = *address_as_ull, assumed;
  do {
    assumed = old;
    old = atomicCAS(address_as_ull, assumed, 
                    __double_as_longlong(val + __longlong_as_double(assumed)));
  } while (assumed != old);
  return __longlong_as_double(old);
}

atomicCAS是cuda中一个把compare和swap组合起来的函数。对应的OpenCL函数是atom_cmpxchg。

有经验的读者会注意到cmpxchg也存在于Intel的汇编指令集,而这条指令常常用来实现琐无关的线程等待机制。具体可参考:http://blog.csdn.net/pongba/article/details/588638

转化成OpenCL中的内联函数,float版本:

inline void AtomicAdd(volatile __global float *source, const float operand) {
    union {
        unsigned int intVal;
        float floatVal;
    } newVal;
    union {
        unsigned int intVal;
        float floatVal;
    } prevVal;
    do {
        prevVal.floatVal = *source;
        newVal.floatVal = prevVal.floatVal + operand;
    } while (atomic_cmpxchg((volatile __global unsigned int *)source, 
                             prevVal.intVal, newVal.intVal) 
                             != prevVal.intVal);
}
对于乘法和除法,可以把其中关键运算的那一行替换

newVal.floatVal = prevVal.floatVal + operand;

替换为

AtomicMul(): newVal.floatVal = prevVal.floatVal * operand; //乘法
AtomicMad(source,operand1,operand2): newVal.floatVal = mad(operand1,operand2,prevVal.floatVal); //乘后相加
AtomicDiv(): newVal.floatVal = prevVal.floatVal / operand;  //除法

不过,浮点数的原子运算效率非常低,所以实际应用中应尽量避免。
来源

http://suhorukov.blogspot.com/2011/12/opencl-11-atomic-operations-on-floating.html

http://d.hatena.ne.jp/aont/20110627/1309192561


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值