Для этих вещей нет никакого волшебного исправления. Это типичная проблема сокращения (где вы хотите объединить несколько результатов в одну переменную).
Вы можете использовать атоматику (но не с поплавковыми значениями), если это не является узким местом вашего алгоритма (т. Е. Вы выполняете другой более дорогостоящий процесс в другом месте ядра). Но если это Ядро ядра. Затем вы должны перейти, чтобы полностью изменить свой алгоритм.
Вы можете начать читать это: http://developer.amd.com/resources/documentation-articles/articles-whitepapers/opencl-optimization-case-study-simple-reductions/
Кроме того, ваш код не так, он фактически никогда не «сливать» s любые данные в res
. он устанавливает только res
в значение C
. И C
является приватным для каждого потока, поэтому он ничего не суммирует. Только последняя нить на самом деле выигрывает datarace, что приводит к ответу будучи 25.
Существует трюк, что я не рекомендую для того, чтобы использовать Atomics в поплавках, на основе профсоюзов и чтения/запись несколько раз в глобальный память:
inline void AtomicAdd(volatile __global float *source, const float operand) {
union {
unsigned int intVal;
float floatVal;
} newVal;
union {
unsigned int intVal;
float floatVal;
} prevVal;
do {
prevVal.floatVal = *source;
newVal.floatVal = prevVal.floatVal + operand;
} while (atomic_cmpxchg((volatile __global unsigned int *)source, prevVal.intVal, newVal.intVal) != prevVal.intVal);
}
__kernel void OUT__1__1527__(__constant float *A,__constant float *B,__global float *res)
{
int i = get_global_id(0);
if (i <= 5 - 1) {
AtomicAdd(res, (A[i] * B[i]));
}
}
хорошо, я обязательно пройду через него. Спасибо за помощь –