Example of C++ “Memory barrier” [duplicate]

此生再无相见时 提交于 2019-12-09 16:08:33

问题


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?


回答1:


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.




回答2:


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

std::atomic<int> i;

All access to i will be protected by memory barriers.




回答3:


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.



来源:https://stackoverflow.com/questions/17898140/example-of-c-memory-barrier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!