【发布时间】:2015-07-07 12:00:18
【问题描述】:
据此https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html,
已发布的存储在 x86(包括 x86-64)上实现为 MOV(进入内存)。
根据他的http://en.cppreference.com/w/cpp/atomic/memory_order
memory_order_release:
具有此内存顺序的存储操作执行释放 操作:当前线程中没有内存访问可以重新排序 在这家店之后。这确保了当前线程中的所有写入 在获取或相同原子变量的其他线程中可见 并且将依赖项携带到原子变量中的写入变为 在消耗相同原子的其他线程中可见。
我了解当使用 memory_order_release 时,之前完成的所有内存存储都应该在此之前完成。
int a;
a = 10;
std::atomic<int> b;
b.store(50, std::memory_order_release); // i can be sure that 'a' is already 10, so processor can't reorder the stores to 'a' and 'b'
问题: 一个简单的MOV 指令(没有显式内存栅栏)怎么可能足以应对这种行为? MOV 如何告诉处理器完成之前的所有存储?
【问题讨论】:
-
你忘了提到“on x86”
-
@cubbi:对,很重要,完成
-
x86 没有单独的发布和获取障碍。
-
该 cppreference 页面的底部有一个指向 x86-TSO 论文的链接,其中包含您将需要的更多详细信息
-
"我可以确定 'a' 已经是 10,因此处理器无法将存储重新排序为 'a' 和 'b" 为清楚起见,在标准中没有全局概念“ 'a' 已经是 10”,所以更准确地说:“我可以确定另一个线程加载存储在 'b' 中的 50 且内存顺序至少为 memory_order_acquire 的另一个线程也会观察到 'a' 为 10。”人们普遍认为,该版本使以前的写入在其他线程中神奇地可见——该标准仅规定来自一个线程的写入应该在“合理的时间内”在其他线程中可见。
标签: c++ c++11 x86 memory-model stdatomic