Sto usando OpenMP e devo usare l'operazione di fetch-and-add. Tuttavia, OpenMP non fornisce una direttiva/chiamata appropriata. Mi piacerebbe preservare la massima portabilità, quindi non voglio fare affidamento sulle intrinseche del compilatore.Fetch-and-add usando le operazioni atomiche di OpenMP
Piuttosto, sto cercando un modo per sfruttare le operazioni atomiche di OpenMP per implementarlo, ma ho raggiunto un punto morto. Questo può essere fatto? N.B., il seguente codice quasi fa quello che voglio:
#pragma omp atomic
x += a
Quasi - ma non del tutto, dal momento che ho davvero bisogno il vecchio valore di x
. fetch_and_add
dovrebbero essere definite per produrre lo stesso risultato come la seguente (solo non bloccabile):
template <typename T>
T fetch_and_add(volatile T& value, T increment) {
T old;
#pragma omp critical
{
old = value;
value += increment;
}
return old;
}
(Una domanda equivalente si può chiedere per confrontare-e-swap ma può essere implementato in termini dell'altra, se non mi sbaglio)
solo dire che 'atomic' non è in realtà ciò che il suo nome sembra promettere, dal momento che qualsiasi thread che ha la memoria modificata da un' atomic' (su qualsiasi altro thread) incassato dovrà essere ri-cache. L'atomico così frequente e ripetuto può uccidere la tua performance (meglio usare le serrature e le scritte di buffer race). – Walter
@Walter Questo è anche ciò che ho trovato empiricamente: algoritmo lock-free che si comporta alla pari con l'algoritmo equivalente che utilizza i lock. E l'algoritmo lock-free utilizza una sincronizzazione molto più complessa, non in termini di prestazioni, ma in termini di logica (e quindi opportunità di introdurre bug). –