实现与浮点数一起使用的自定义atomic_add()

问题描述 投票:1回答:1

我试图遵循https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html的B.12部分进行原子添加,它适用于浮点数。简单地从那里复制和粘贴代码并将类型更改为浮动不起作用,因为我无法执行从GLOBAL到PRIVATE的转换指针转换,这是atomicCAS操作所必需的。为了解决这个问题,我决定使用atomic_xchg(),因为它适用于浮点数,并使用额外的if语句来实现与atomicCAS相同的功能。但是,每当我运行程序时,当我在大浮点矢量上执行加法时,这会返回不同的答案。

我已经尝试弄清楚如何克服从GLOBAL到PRIVATE的显式转换,但老实说我不知道​​如何做到这一点,当我执行加法时,地址参数被改变而不是一些临时变量。

kernel void atomicAdd_2(volatile global float* address, float value)
{
    float old = *address, assumed;

    do {
        assumed = old;
        if (*address == assumed) {
            old = atomic_xchg(address, value + assumed);
        }
        else{
            old = *address;
        }
        // Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN)
    } while (assumed != old);
}

这是我为浮点数实现的atomicAdd。

kernel void reduce_add(global const float* input, global float* output) {
         float temp = 242.23f;
         atomicAdd_floats(&output[0], temp);
         printf(" %f ", output[0]);

}

这是我向atomicAdd_floats提供参数的函数。请注意,我的输入参数包含一个浮点向量,输出参数只是我想要存储结果的位置,特别是在输出向量输出[0]的第一个元素中;但相反,当我printf(“%f”,输出[0]);它显示我的默认初始化值0。

Comparison of serially computed ground truth sum against parallel output B

c++ parallel-processing opencl
1个回答
0
投票

首先,我建议删除atomicAdd_2函数上的“kernel”关键字。 “kernel”应仅用于您打算从主机入队的函数。第二,有一些原子加浮动on the net.的OpenCL实现

然后,我有点困惑你要做什么。你是在尝试对一个向量求和,并在私有变量中得到总和吗?如果是这样,使用atomicAdd是没有意义的。私有内存总是原子的,因为它是私有的。原型只需要全球和本地的记忆,因为它们是共享的。否则我不确定你为什么提到改变地址或GLOBAL改为PRIVATE。

无论如何,来自链接的代码应该可以工作,尽管它相对较慢。如果sum的向量很大,那么最好使用不同的算法(wtth partial sums)。尝试谷歌搜索“opencl parallel sum”等。

© www.soinside.com 2019 - 2024. All rights reserved.