После этого link, я пытаюсь реализовать атомную функцию, которая вычисляет сумму массива double, поэтому я реализовал свою собственную функцию atom_add
(для двойного).OpenCL - Атомная операция с двойным действием до предела
Вот код ядра используется:
#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]);
}
Моя проблема заключается в том, что коды ядра генерирует хорошие результаты, пока не достигнет примерно 100 000 элементов для размера input
массива.
За этот предел, то вычисление не действует больше (я могу проверить результат легко, потому что в моем тесте я заполнить массив входной петлей for(i=0;i<sizeArray;i++) input[i]=i+1;
, поэтому сумма равна sizeArray*(sizeArray+1)/2
.
Любой уже получил такую ошибку?
Могу ли я определить и поставить функцию как atom_add_double
в коде ядра?
Любая помощь приветствуется, спасибо
Как я уже говорил, не используйте атомику для уменьшения, и, пожалуйста, не используйте атомы, которые блокируют потоки, они еще хуже. Используйте надлежащий код сокращения или функции уменьшения CL 2.0. https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/work_group_reduce.html Мы говорим о 10-кратном снижении производительности (по крайней мере) при использовании атоматики против правильной параллельной редукции. – DarkZeros