这是在x86/x86_64中实现顺序一致性的四种方法:
就像这里写的:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
注意:还有C/C++ 11到x86的替代映射,它不是锁定(或隔离)Seq Cst存储区,而是锁定/设置Seq Cst负载:
GCC 4.8.2(x86_64中的GDB)对C++11-std::memory_order_seq_cst使用first(1)方法,即LOAD(无围栏)和STORE + MFENCE:
std::atomic<int> a;
int temp = 0;
a.store(temp, std::memory_order_seq_cst);
0x4613e8 <+0x0058> mov 0x38(%rsp),%eax
0x4613ec <+0x005c> mov %eax,0x20(%rsp)
0x4613f0 <+0x0060> mfence
众所周知,MFENCE = LFENCE + SFENCE。然后,我们可以将此代码重写为:
LOAD(without fence) and STORE+LFENCE+SFENCE
问题:
最佳答案
x86唯一的重新排序(用于正常的内存访问)是,它可能会重新排序存储后的负载。
SFENCE保证栅栏之前的所有商店在栅栏之后的所有商店之前完成。 LFENCE保证栅栏之前的所有负载在栅栏之后的所有负载之前完成。对于普通的内存访问,默认情况下已经提供了单个SFENCE或LFENCE操作的顺序保证。基本上,LFENCE和SFENCE本身仅对x86的较弱内存访问模式有用。
LFENCE,SFENCE或LFENCE + SFENCE都不能防止对存储紧随其后的存储进行重新排序。 MFENCE确实如此。
相关引用是《 Intel x86体系结构手册》。