Entrambe MemoryBarrier
(MSVC) e _mm_mfence
(supportate da diversi compilatori) forniscono una memoria di memoria hardware, che impedisce al processore di spostare le letture e le scritture attraverso la recinzione.
La differenza principale è che MemoryBarrier ha implementazioni specifiche per piattaforma x86, x64 e IA64, dove come _mm_mfence utilizza specificamente l'istruzione SS, quindi non è sempre disponibile.
Su x86 e x64 MemoryBarrier è implementato con un xchg
e lock or
rispettivamente, e ho visto alcune affermazioni che questo è più veloce di mfence. Tuttavia i miei benchmark mostrano il contrario, quindi apparentemente dipende molto dal modello del processore.
Un'altra differenza è che mfence può anche essere utilizzato per ordinare negozi/carichi non temporali (movntq
ecc.).
GCC dispone anche di __sync_synchronize
che genera una recinzione hardware.
asm volatile ("" : : : "memory")
in GCC e _ReadWriteBarrier
in MSVC forniscono solo un recinto di memoria a livello di compilatore, impedendo al compilatore di riordinare gli accessi alla memoria. Ciò significa che il processore è ancora libero di riordinare.
Le recinzioni del compilatore sono generalmente utilizzate in combinazione con operazioni che presentano una sorta di recinzione hardware implicita. Per esempio. su x86/x64 tutti i negozi hanno un recinto di rilascio e i carichi hanno un recinto di acquisizione, quindi è sufficiente un recinto del compilatore quando si implementa l'acquisizione del carico e lo store-release.
ti sei dimenticato di C++ 11s 'atomic_thread_fence' – Grizzly
Beh, questo è ciò che sta portando a ... abbiamo il nostro oggetto template atomico per i tipi interi e sto volendo passare agli atomici standard C++ 11. Prima di farlo, voglio capire l'implementazione di base di come funzionano entrambi. – AJG85