gpt4 book ai didi

c++ - 实现与 float 一起使用的自定义 atomic_add()

转载 作者:太空宇宙 更新时间:2023-11-04 12:38:42 25 4
gpt4 key购买 nike

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

我已经尝试弄清楚如何克服从 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);
}

这是我为 float 实现的 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 提供参数的函数。请注意,我的输入参数包含一个浮点 vector ,而输出参数只是我要存储结果的位置,特别是在输出 vector output[0] 的第一个元素中;但是当我 printf("%f ", output[0]);它显示我的默认初始化值 0。

Comparison of serially computed ground truth sum against parallel output B

最佳答案

首先,我建议删除 atomicAdd_2 函数上的“kernel”关键字。 “内核”应该仅用于您打算从主机排队的功能。第二,有 atomic-add-float on the net. 的 OpenCL 实现。

然后,我对您要尝试做的事情感到有点困惑。您是否尝试对 vector 求和,同时将总和保存在私有(private)变量中?如果是这样,使用 atomicAdd 就没有意义了。私有(private)内存始终是原子的,因为它是私有(private)的。只有全局和本地内存需要原子性,因为它们是共享的。否则我不确定您为什么提到将地址或 GLOBAL 更改为 PRIVATE。

无论如何,链接中的代码应该可以工作,尽管它相对较慢。如果要求和的 vector 很大,则最好使用不同的算法(部分求和)。尝试使用谷歌搜索“opencl parallel sum”等。

关于c++ - 实现与 float 一起使用的自定义 atomic_add(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55314581/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com