对于std::atomic<T>T是基本类型的任何地方:
如果我使用std::memory_order_acq_rel的fetch_xxx操作,以及std::memory_order_acquire用于load操作和std::memory_order_release对store操作盲目(我的意思是,就像重置这些功能的默认内存排序)
std::memory_order_seq_cst(用作默认值)的任何声明操作相同?std::memory_order_seq_cst在效率方面是否与使用不同?标准C++ 11是否保证memory_order_seq_cst阻止StoreLoad重新排序原子操作以进行非原子内存访问?
众所周知,std::memory_orderC++ 11中有6 个,它指定了如何围绕原子操作对常规的非原子内存访问进行排序 - 工作草案,编程语言C++标准2016-07-12:http:/ /www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
§29.3顺序和一致性
§29.3/ 1
枚举memory_order指定1.10中定义的详细常规(非原子)内存同步顺序,并且可以提供操作排序.其枚举值及其含义如下:
众所周知,这6个memory_orders会阻止其中一些重新排序:
但是,是否会memory_order_seq_cst阻止StoreLoad围绕原子操作重新排序以进行常规的非原子内存访问,或仅针对其他具有相同原子的原子进行重新排序memory_order_seq_cst?
即,如果我们同时使用std::memory_order_seq_cstSTORE和LOAD,或仅用于其中一个,则阻止此StoreLoad重新排序?
std::atomic<int> a, b;
b.store(1, std::memory_order_seq_cst); // Sequential Consistency
a.load(std::memory_order_seq_cst); // Sequential Consistency
Run Code Online (Sandbox Code Playgroud)
关于Acquire-Release语义是明确的,它完全指定了跨原子操作的非原子内存访问重新排序:http://en.cppreference.com/w/cpp/atomic/memory_order
为防止StoreLoad重新排序,我们应该使用std::memory_order_seq_cst.
两个例子:
std::memory_order_seq_cst对于STORE和LOAD:有MFENCE StoreLoad无法重新排序 - GCC 6.1.0 x86_64:https://godbolt.org/g/mVZJs0
std::atomic<int> a, b;
b.store(1, std::memory_order_seq_cst); // can't be executed after LOAD
a.load(std::memory_order_seq_cst); // …Run Code Online (Sandbox Code Playgroud) 8.2.3.4负载可以通过早期存储
重新排序到不同位置 Intel-64内存排序模型允许将负载与早期存储重新排序到不同位置.但是,加载不会与商店重新排序到同一位置.
那些与之前的商店部分或完全重叠但是没有相同起始地址的负载呢?(有关具体案例,请参阅本文末尾)
假设以下类似C的代码:
// lock - pointer to an aligned int64 variable
// threadNum - integer in the range 0..7
// volatiles here just to show direct r/w of the memory as it was suggested in the comments
int TryLock(volatile INT64* lock, INT64 threadNum)
{
if (0 != *lock)
return 0; // another thread already had the lock
((volatile INT8*)lock)[threadNum] = 1; // take the lock by setting our byte
if (1LL << 8*threadNum != …Run Code Online (Sandbox Code Playgroud)