What Is a Memory Barrier?
Memory barriers, also known as memory barriers, memory barriers, barrier instructions, etc., are a type of synchronization barrier instruction, which is a synchronization point for random access operations on the memory by the CPU or compiler, making all read and write operations before this point Only after this is done can the operations after this point be started.
- Most modern computers take
- Most processors provide memory barrier instructions:
- A full memory barrier ensures that the results of memory read and write operations that are earlier than the barrier are submitted to memory, and then read and write operations that are later than the barrier are performed.
- The read memory barrier only ensures memory read operations;
- The write memory barrier only guarantees memory write operations.
- Memory barriers are low-level primitives and part of memory sequencing. They vary widely under different architectures and are not suitable for generalization. The hardware manual needs to be carefully studied to determine the memory barrier approach. The memory barrier instructions in the x86 instruction set are:
lfence (asm), void _mm_lfence (void) read operation barrier sfence (asm), void _mm_sfence (void) [1] write operation barrier mfence (asm), void _mm_mfence (void) [2] read and write operation barrier
- Common x86 / x64 are usually implemented by using the lock instruction prefix and a no-op operation. Note that of course it cannot be a nop instruction, but there are actually many instructions that can be used to implement the no-op operation.
addl $ 0, 0 (% esp)
- Memory also provides another set of semantic memory barrier instructions:
- acquire semantics: The result of this operation can take advantage of the results of all subsequent operations in the code.
- release semantics: The result of this operation can take advantage of the results of all previous operations in the code.
- Fence semantics: acquire and release are both valid. That is, the operation result can take advantage of the results of all previous operations in the code, and the operation result can take advantage of the results of all subsequent operations in the code.
- Intel Itanium processor, with memory barrier mf instructions, with the following modifiers [1]
- The following synchronization functions use proper barriers to ensure memory ordering:
- Functions in and out of the critical section
- Function that triggers (signaled) a synchronization object
- Wait function
- Interlocked function [1]
- Multithreaded programs often use synchronization primitives in high-level programming languages, such as
- In C and C ++, the volatile keyword is intended to allow memory-mapped I / O operations. This requires the compiler to read and write data in this program in the order in which it can't be reordered. Therefore the keyword volatile is not guaranteed to be a memory barrier.
- For Visual Studio 2003, the compiler guarantees that volatile operations are in order, but it cannot guarantee out-of-order execution of the processor. Therefore, you can use InterlockedCompareExchange or InterlockedExchange functions.
- For Visual Studio 2005 and later, the compiler uses acquire semantics for reads of volatile variables and release semantics for writes. [1]
- The compiler will optimize the generated executable code, causing out-of-order execution or even omission (not execution). The gcc compiler encountered an inline assembly statement:
asm volatile ("" ::: "memory");
- Use this as a memory barrier to reorder memory operations. That is, various compilation optimizations before this statement will not continue after this statement. Also available with built-in __sync_synchronize
- The compiler memory barrier for Microsoft Visual C ++ is:
_ReadWriteBarrier () MemoryBarrier ()
- The memory barrier of the Intel C ++ compiler is [1] :
__memory_barrier ()