Estoy usando OpenMP y necesito usar la operación de búsqueda y agregación. Sin embargo, OpenMP no proporciona una directiva/llamada apropiada. Me gustaría preservar la máxima portabilidad, por lo tanto, no quiero confiar en los intrínsecos del compilador.Fetch-and-add usando las operaciones atómicas de OpenMP
Más bien, estoy buscando una manera de aprovechar las operaciones atómicas de OpenMP para implementar esto, pero he llegado a un callejón sin salida. ¿Puede esto siquiera estar terminado? N. B., el siguiente código casi hace lo que yo quiero:
#pragma omp atomic
x += a
Casi - pero no del todo, ya que realmente necesito el antiguo valor de x
. fetch_and_add
deberían definirse para producir el mismo resultado que el siguiente (sólo sin bloqueo):
template <typename T>
T fetch_and_add(volatile T& value, T increment) {
T old;
#pragma omp critical
{
old = value;
value += increment;
}
return old;
}
(Una cuestión equivalentes se les puede pedir para-y-canje de comparar, pero uno puede ser implementada en términos de la otra, si no me equivoco)
sólo para decir que 'atomic' no es realmente lo que su nombre parece prometer, ya que cualquier hilo que tenga la memoria modificada por un' atomic' (en cualquier otro hilo) deberá cambiarse a caché. Tan frecuente y repetido 'atómico' puede matar su rendimiento (mejor uso de bloqueos y escritura de búfer de carreras). – Walter
@Walter Eso también es lo que encontré empíricamente: algoritmo sin bloqueo que funciona justo a la par con el algoritmo equivalente que usa bloqueos. Y el algoritmo sin bloqueo utiliza una sincronización mucho más compleja, no en términos de rendimiento sino en términos de lógica (y por lo tanto, oportunidades para introducir errores). –