我使用atomicMax()
来查找CUDA内核中的最大值:
__global__ void global_max(float* values, float* gl_max)
{
int i=threadIdx.x + blockDim.x * blockIdx.x;
float val=values[i];
atomicMax(gl_max, val);
}
抛出以下错误:
错误:没有重载函数的实例“atomicMax”匹配参数列表
参数类型为:(float *, float)
。
答案 0 :(得分:23)
atomicMax
不适用于浮动类型。但您可以通过atomicCAS
实现它:
__device__ static float atomicMax(float* address, float val)
{
int* address_as_i = (int*) address;
int old = *address_as_i, assumed;
do {
assumed = old;
old = ::atomicCAS(address_as_i, assumed,
__float_as_int(::fmaxf(val, __int_as_float(assumed))));
} while (assumed != old);
return __int_as_float(old);
}
答案 1 :(得分:7)
您需要将 float映射到orderedIntFloat 以使用 atomicMax !
__device__ __forceinline__ int floatToOrderedInt( float floatVal ) {
int intVal = __float_as_int( floatVal );
return (intVal >= 0 ) ? intVal : intVal ^ 0x7FFFFFFF;
}
__device__ __forceinline__ float orderedIntToFloat( int intVal ) {
return __int_as_float( (intVal >= 0) ? intVal : intVal ^ 0x7FFFFFFF);
}
答案 2 :(得分:3)
简短的回答是否定的。正如您在atomic function documentation中看到的那样,atomicMax
仅支持整数参数,并且仅在计算能力3.5设备上支持64位整数参数。
答案 3 :(得分:2)
基于CUDA Toolkit Documentation v9.2.148,没有用于float的原子操作。 但是我们可以通过将atomicMax和atomicMin与有符号和无符号整数转换混合来实现它!
这是一个浮动原子最小值:
__device__ __forceinline__ float atomicMinFloat (float * addr, float value) {
float old;
old = (value >= 0) ? __int_as_float(atomicMin((int *)addr, __float_as_int(value))) :
__uint_as_float(atomicMax((unsigned int *)addr, __float_as_uint(value)));
return old;
}
这是一个浮动原子最大值:
__device__ __forceinline__ float atomicMaxFloat (float * addr, float value) {
float old;
old = (value >= 0) ? __int_as_float(atomicMax((int *)addr, __float_as_int(value))) :
__uint_as_float(atomicMin((unsigned int *)addr, __float_as_uint(value)));
return old;
}
答案 4 :(得分:0)
这是Atomic MAX的语法
int atomicMax(int* address,int val);
但是像atomicAdd这样的异常支持浮点数。