Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Example of C++ "Memory barrier" [duplicate]

I was reading the answer to this question regarding the volatile keyword:

https://stackoverflow.com/a/2485177/997112

The person says:

The solution to preventing reordering is to use a memory barrier, which indicates both to the compiler and the CPU that no memory access may be reordered across this point. Placing such barriers around our volatile variable access ensures that even non-volatile accesses won't be reordered across the volatile one, allowing us to write thread-safe code.

However, memory barriers also ensure that all pending reads/writes are executed when the barrier is reached, so it effectively gives us everything we need by itself, making volatile unnecessary. We can just remove the volatile qualifier entirely.

How is this "memory barrier" implemented in C++?

EDIT:

Could someone give a simple code example please?

like image 651
user997112 Avatar asked Jul 27 '13 13:07

user997112


People also ask

What is memory barrier in C?

In computing, a memory barrier, also known as a membar, memory fence or fence instruction, is a type of barrier instruction that causes a central processing unit (CPU) or compiler to enforce an ordering constraint on memory operations issued before and after the barrier instruction.

How are memory barriers implemented?

Memory barrier is implemented by the hardware processor. CPUs with different architectures have different memory barrier instructions. Therefore, the programmer needs to explicitly call memory barrier in the code to solve the preceding problem.

What is write memory barrier?

A write memory barrier gives a guarantee that all the STORE operations specified before the barrier will appear to happen before all the STORE operations specified after the barrier with respect to the other components of the system.

What is C++ memory model?

• The C++ memory model describes an abstract relation. between threads and memory. • The model makes guarantees about properties concerning. interaction between instruction sequences and variables in. memory.


3 Answers

This is very hardware-dependent. From the fairly long documentation of memory barrier of the Linux kernel:

The Linux kernel has eight basic CPU memory barriers:

TYPE                MANDATORY               SMP CONDITIONAL
===============     ======================= ===========================
GENERAL             mb()                    smp_mb()    
WRITE               wmb()                   smp_wmb()
READ                rmb()                   smp_rmb()   
DATA DEPENDENCY     read_barrier_depends()  smp_read_barrier_depends()

Let's take one of them in particular: smp_mb(). If you open asm/x86/um/asm/barrier.h, you will find that when CONFIG_SMP is defined,

#define smp_mb()    mb()

And if you scroll up, you can see that depending on the platform, mb has different implementations:

// on x86-32
#define mb()        alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
// on other platforms
#define mb()        asm volatile("mfence" : : : "memory")

More information on the differences between these 2 things have been discussed in this thread. I hope this helps.

like image 121
qdii Avatar answered Nov 28 '22 12:11

qdii


Memory barriers are trivial to use in C++11:

std::atomic<int> i;

All access to i will be protected by memory barriers.

like image 29
Pete Becker Avatar answered Nov 28 '22 13:11

Pete Becker


Typically, there are "intrinsic functions" - these are special functions that the compiler has special knowledge as to how they operate (in particular that they are memory barriers). The names vary from compiler to compiler (and sometimes for different architectures of the same compiler).

For example, MSVC uses _ReadBarrier, WriteBarrier and _ReadWriteBarrier

In x86 it would produce an lfence, sfence or mfence instruction - which, respectively, does "load", "store" and "all memory operations" barriers - in other words, an lfence will be a barrier for memory read operations, an sfence will be a "memory write" barrier, and mfence will be a barrier against both read and write operations.

like image 24
Mats Petersson Avatar answered Nov 28 '22 12:11

Mats Petersson