c++11的std::memory_order

首先明确一点,std::atmoic和std::memory_order只有在多cpu多线程情况下,无锁编程才会用到。在x86下,由于是strong memory order的,所以很多时候只需要考虑编译器优化的memory order;保险起见,可以用std::atomic,他会同时处理编译器优化和cpu的memory reorder(虽然x86用不到)。在除非必要的情况下,不用使用std::memory_order,std::atmoic默认用的是最强限制。见这句话:do not use anything other than std::memory_order_seq_cst (the default) unless (a) you really really know what you are doing, and can prove that the relaxed usage is safe in all cases, and (b) your profiler demonstrates that the data structure and operations you are intending to use the relaxed orderings with are a bottleneck. 据说能把这玩意完全搞清楚的,全球一个巴掌数得清!

摘要1

The std::memory_order values allow you to specify fine-grained constraints on the memory ordering provided by your atomic operations. If you are modifying and accessing atomic variables from multiple threads, then passing the std::memory_order values to your operations allow you to relax the constraints on the compiler and processor about the order in which the operations on those atomic variables become visible to other threads, and the synchronization effects those operations have on the non-atomic data in your application.

The default ordering of std::memory_order_seq_cst is the most constrained, and provides the "intuitive" properties you might expect: if thread A stores some data and then sets an atomic flag using std::memory_order_seq_cst, then if thread B sees the flag is set then it can see that data written by thread A. The other memory ordering values do not necessarily provide this guarantee, and must therefore be used very carefully.

The basic premise is: do not use anything other than std::memory_order_seq_cst (the default) unless (a) you really really know what you are doing, and can prove that the relaxed usage is safe in all cases, and (b) your profiler demonstrates that the data structure and operations you are intending to use the relaxed orderings with are a bottleneck.

My book, C++ Concurrency in Action devotes a whole chapter (45 pages) to the details of the C++ memory model, atomic operations and the std::memory_order constraints, and a further chapter (44 pages) to using atomic operations for synchronization in lock-free data structures, and the consequences of relaxed ordering constraints.

My blog entries on Dekker's algorithm and Peterson's algorithm for mutual exclusion demonstrate some of the issues.

摘要2

In brief, your compiler and CPU may execute instructions in order different from how you have written them. For a single-thread this is not an issue as it will appear correct. For multiple threads on multiple processors this becomes an issue. Memory ordering in C++ restricts what your compiler/CPU can do and fixes such issues.

For example, if you look at my article on double-check locking you can see how ordering messes with that pattern -- it mention show atomic memory ordering can be used to fix it.

About the reordering itself you can also consider CPU Reordering -- again, the compiler may also be doing reorders as well.

Be aware that any documents on this topic (including mine) offer speak of theoretical scenarios. The most common CPUs, like x86, have very strong ordering guarantees such that a lot of explicit ordering is simply not needed. Thus even if you don't use the proper C++11 atomics your code will likely still work.

As zvrba mentioned, the topic is actually quite detailed. The linux kernel doc on memory barriers also contains a lot of detailed information.

Stack Overflow: c++, std::atomic, what is std::memory_order and how to use them?

C++ atomics and memory ordering

std::memory_order

你可能感兴趣的:(C++,constraints,compiler,profiler,structure,variables)