CUDA编程 原子操作atomicAdd报错err:MSB3721,返回代码1

问题:原子操作atomicAdd()报错err:MSB3721,返回代码1。

直接原因: 双精度double的原子操作尽在仅在计算能力为6.0以上的设备支持,但我的设备太LOW。

问题描述: 今天在编写利用cuda加速三维点云重建后的计算法向相关代码,有一步骤需要对点云间距统计后求得平均点距。这就要求多个线程对不同点与邻点的距离进行相加,之后再除以点的个数。
  但是如果没有原子操作atomicAdd()的话,相加结果会无法避免的出现错误。类似于OpenMP进行并行for循环锁住加和变量保证变量正确加和的原理。
  但是由于点距是double类型,无知的我直接使用atomicAdd()进行点距相加导致编译出错err:MSB3721,返回代码1,经过搜索官方文档后得知,对于双精度double类型的原子操作atomicAdd(),仅在计算能力大于6.0的机器上支持,对于我这种计算能力只有3.5的老年机器GT720,无法成功编译。至此找到了最终原因。详看黄色字符。
在这里插入图片描述
解决方案: 但是官方也给了我们这种老GPU活路,使用图中的代码可以实现计算能力小于6.0的设备进行双精度double原子操作。
【注意:复制以下代码,不要直接使用官网代码,否则出现重定义操作符的报错】

#if define (__CUDA_ARCH__)||__CUDA_ARCH__ < 600
__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)));

    // Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN)
    } while (assumed != old);

    return __longlong_as_double(old);
}
#endif

如果该方法能用,麻烦给个点赞收藏加关注吧!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值