gpt4 book ai didi

c - OpenCL - 双重原子操作 - 工作到极限

转载 作者:行者123 更新时间:2023-12-01 23:29:26 26 4
gpt4 key购买 nike

关注此link ,我尝试实现一个计算 double 组总和的原子函数,所以我实现了自己的 atom_add功能(双)。

这是使用的内核代码:

#pragma OPENCL EXTENSION cl_khr_fp64: enable
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable

void atom_add_double(__global double *val, double delta)
{
union {
double f;
ulong i;
} old, new;

do
{
old.f = *val;
new.f = old.f + delta;
}
while (atom_cmpxchg((volatile __global ulong *)val, old.i, new.i) != old.i);

}

__kernel void sumGPU ( __global const double *input,
__global double *finalSum
)
{
// Index of current workItem
uint gid = get_global_id(0);

// Init sum
*finalSum = 0.0;

// Compute final sum
atom_add_double(finalSum, input[gid]);

}

我的问题是内核代码会生成良好的结果,直到我达到大约 100000 个元素大小为 input数组。

超过这个限制,计算不再有效(我可以很容易地检查结果,因为在我的测试用例中,我通过循环填充输入数组 for(i=0;i<sizeArray;i++) input[i]=i+1; ,所以总和等于 sizeArray*(sizeArray+1)/2 ) .

我可以定义并放置一个类似 atom_add_double 的函数吗?进入内核代码?

最佳答案

@huseyin 的回答是正确的,可以解决问题。

但是,我忍不住要说“不要使用原子来减少。”

更糟糕的是,锁定在 while 循环中并直接访问全局数据的原子。我们可能至少在谈论 10 倍的性能损失。

如果可以,请使用 proper automatic reduction (CL 2.0+) .

__kernel void sumGPU(__global const double *input, __global double *finalSum)
{
// Index of current workItem
uint gid = get_global_id(0);

// Sum locally without atomics
double sum = work_group_scan_inclusive_add(input[gid]);

// Compute final sum using atomics
// but it is even better if just store them in an array and do final sum in CPU
// Only add the last one, since it contains the total sum
if (get_local_id(0) == get_local_size(0) - 1) {
atom_add_double(finalSum, sum);
}
}

关于c - OpenCL - 双重原子操作 - 工作到极限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41850461/

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