【发布时间】:2017-01-25 11:28:20
【问题描述】:
按照这个link,我尝试实现一个计算双精度数组总和的原子函数,因此我实现了自己的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]);
}
我的问题是内核代码会产生良好的结果,直到我达到 input 数组大小的大约 100000 个元素。
超过这个限制,计算不再有效(我可以很容易地检查结果,因为在我的测试用例中,我用循环填充输入数组for(i=0;i<sizeArray;i++) input[i]=i+1;,所以总和等于sizeArray*(sizeArray+1)/2) .
我可以定义像atom_add_double这样的函数并将其放入内核代码中吗?
【问题讨论】:
-
正如我已经告诉过你的,不要使用原子来减少,也请不要使用锁定线程的原子,它们更糟糕。使用适当的归约代码或 CL 2.0 归约函数。 khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/… 我们谈论的是使用原子与适当的并行缩减时(至少)10 倍的性能损失。