¿Por qué ya no haya atomicAdd()
en dobles sido implementados de manera explícita como parte de CUDA 4.0 o superior?¿Por qué no se ha implementado atomicAdd para dobles?
A partir del apéndice F Página 97 del CUDA programming guide 4.1 se han implementado las siguientes versiones de atomicAdd.
int atomicAdd(int* address, int val);
unsigned int atomicAdd(unsigned int* address,
unsigned int val);
unsigned long long int atomicAdd(unsigned long long int* address,
unsigned long long int val);
float atomicAdd(float* address, float val)
La misma página va a dar una pequeña aplicación de atomicAdd en dobles de la siguiente manera que acabo de comenzar a utilizar en mi proyecto.
__device__ double atomicAdd(double* address, double val)
{
unsigned long long int* address_as_ull =
(unsigned long long int*)address;
unsigned long long int old = *address_as_ull, assumed;
do {
assumed = old;
old = atomicCAS(address_as_ull, assumed,
__double_as_longlong(val +
__longlong_as_double(assumed)));
} while (assumed != old);
return __longlong_as_double(old);
}
¿Por qué no definir el código anterior como parte de CUDA?
Probablemente por lo que todos los usuarios de la misma es consciente de su implementación, ya que no es un sistema incorporado en la instrucción y la lógica de reintento puede estar sujeto a livelocks (ya que no hay garantía de equidad, un hilo puede quedar estancado durante el siempre que haya otros hilos actualizando la misma variable). – tera