Tanto MemoryBarrier
(MSVC) como _mm_mfence
(admitidos por varios compiladores) proporcionan una valla de memoria de hardware, que evita que el procesador mueva lecturas y escrituras a través de la guía.
La principal diferencia es que MemoryBarrier tiene implementaciones específicas de plataforma para x86, x64 e IA64, donde como _mm_mfence utiliza específicamente la instrucción SSE2 mfence
, por lo que no siempre está disponible.
En x86 y x64 MemoryBarrier se implementa con un xchg
y lock or
respectivamente, y he visto algunas afirmaciones de que esto es más rápido que mfence. Sin embargo, mis propios puntos de referencia muestran lo contrario, por lo que aparentemente depende mucho del modelo de procesador.
Otra diferencia es que mfence también se puede usar para ordenar tiendas/cargas no temporales (movntq
, etc.).
GCC también tiene __sync_synchronize
que genera una cerca de hardware.
asm volatile ("" : : : "memory")
en GCC y _ReadWriteBarrier
en MSVC solo proporcionan una valla de memoria de nivel de compilación, evitando que el compilador reordena los accesos a la memoria. Eso significa que el procesador todavía está en libertad de hacer un nuevo pedido.
vallas compilador se utilizan generalmente en combinación con las operaciones que tienen algún tipo de valla de hardware implícita. P.ej. en x86/x64 todas las tiendas tienen una valla de liberación y las cargas tienen una valla de adquisición, por lo que solo necesita una valla de compilación cuando implemente load-acquire y store-release.
se olvidó de C++ 11s 'atomic_thread_fence' – Grizzly
Bueno, eso es lo que esto conduce a ... tenemos nuestro propio objeto plantilla atómica para tipos integrales y estoy queriendo cambiar a C++ 11 estándar atómico. Antes de hacerlo, quiero entender la implementación subyacente de cómo funcionan ambas cosas. – AJG85