2013-09-23 1 views
2

Мне нужна функция атомного максимума для float в OpenCL. Это мой текущий наивным код с помощью atomic_xchgAtomic max для поплавков в OpenCL

float value = data[index]; 
if (value > *max_value) 
{ 
    atomic_xchg(max_value, value); 
} 

Этот код дает правильный результат при использовании процессора Intel, но не для GPU Nvidia. Правильно ли этот код, или кто-нибудь может мне помочь?

+0

Похоже, что с этой проблемой столкнулись другие. Например: https://devtalk.nvidia.com/default/topic/408491/atomicmax-with-floats/ – ScottD

+1

Документация cuda объясняет, как реализовать атомные функции для float/double, используя compare-swap http: //docs.nvidia. com/cuda/cuda-c-programming-guide/index.html # атомные функции тоже могут быть выполнены на opencl – krishnaraj

ответ

5

Вы можете сделать это следующим образом:

//Function to perform the atomic max 
inline void AtomicMax(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 = max(prevVal.floatVal,operand); 
    } while (atomic_cmpxchg((volatile __global unsigned int *)source, prevVal.intVal, newVal.intVal) != prevVal.intVal); 
} 

__kernel mykern(__global float *data, __global float *max_value){ 
    unsigned int index = get_global_id(0); 

    float value = data[index]; 
    AtomicMax(max_value, value); 
} 

Как указано в LINK.

Что он делает, это создать объединение float и int. Выполните математику на float, но сравните целые числа при выполнении атомарного xchg. Пока целые числа совпадают, операция завершается.

Однако снижение скорости из-за использования этих методов очень велико. Используйте их осторожно.

+0

Как это обрабатывать целые числа, соответствующие float NaN? –

+0

A NaN определяется как 's111 1111 1axx xxxx xxxx xxxx xxxx xxxx', где' '' знак (-NaN, NaN) часто игнорируется, а 'a' указывает, является ли это спокойным NaN. Итак, в конце концов, NaN является действительным целым числом и будет работать точно так же хорошо. Однако, как определено OpenCL. Операция 'max()' игнорирует любое введенное значение NaN и получает только максимальное допустимое значение. Верхний код будет работать точно так же хорошо с NaNs (после Spec). – DarkZeros

Смежные вопросы