以下是在x86/x86_64中实现顺序一致性的四种方法:
正如这里所写的:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
C/C++11操作x86实现
注意: C/C++11与x86之间有另一种映射,而不是锁定(或栅栏) Seq存储锁/栅栏-- Seq负载:
GCC 4.8.2(GDB in x86_64)对科技委采用第一(1)种方法,即荷载(无栅栏)和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
问题:
发布于 2013-10-12 11:30:16
x86所做的唯一的重新排序(对于正常的内存访问)是,它可能会重新排序存储后的负载。
SFENCE保证在栅栏之前的所有商店在栅栏之后完成所有的商店。LFENCE保证在栅栏之前的所有负载都在栅栏之后完成。对于正常的内存访问,默认情况下已经提供了单个SFENCE或LFENCE操作的排序保证。基本上,LFENCE和SFENCE本身仅适用于x86较弱的内存访问模式。
无论是LFENCE、SFENCE还是LFENCE + SFENCE都不能防止存储后的负载被重新排序。是的。
相关参考是英特尔x86架构手册。
发布于 2013-09-30 07:12:50
考虑以下代码:
#include <atomic>
#include <cstring>
std::atomic<int> a;
char b[64];
void seq() {
/*
movl $0, a(%rip)
mfence
*/
int temp = 0;
a.store(temp, std::memory_order_seq_cst);
}
void rel() {
/*
movl $0, a(%rip)
*/
int temp = 0;
a.store(temp, std::memory_order_relaxed);
}对于原子变量"a",seq()和rel()在x86体系结构中都是有序的和原子的,因为:
不需要栅栏将常量值存储到原子变量中。之所以存在栅栏,是因为std::memory_order_seq_cst意味着所有内存都是同步的,而不仅仅是保存原子变量的内存。
这种效果可以通过以下集合和get函数来演示:
void set(const char *s) {
strcpy(b, s);
int temp = 0;
a.store(temp, std::memory_order_seq_cst);
}
const char *get() {
int temp = 0;
a.store(temp, std::memory_order_seq_cst);
return b;
}strcpy是一个库函数,如果在运行时可用,它可能使用更新的sse指令。由于sse指令在旧处理器中不可用,因此不需要向后兼容,内存顺序也没有定义。因此,一个线程中的strcpy的结果可能在其他线程中不可直接看到。
上面的set和get函数使用一个原子值来执行内存同步,以便strcpy的结果在其他线程中变得可见。现在,篱笆很重要,但是它们在调用原子::存储中的顺序并不重要,因为在原子::store中不需要内部的栅栏。
发布于 2015-09-22 02:09:44
SFENCE + LFENCE是而不是a StoreLoad屏障,所以问题的前提是不正确的。(还请参阅我从同一个用户为什么是(或者不是?)SFENCE + LFENCE相当于MFENCE?获得的关于同一问题的另一个版本的答案)
LFENCE+SFENCE不包括任何能阻止存储在稍后加载后才被缓冲的内容。MFENCE 可以通过来防止这种情况发生。
普林的博客文章用图表更详细地解释了StoreLoad障碍是如何特殊的,并有一个工作代码的实际示例,演示了不使用MFENCE的重新排序。任何对内存排序感到困惑的人都应该从这个博客开始。
x86有一个强记忆模型,每个普通存储都有发布语义,每个普通负载都有获取语义。这篇文章有详细信息。
LFENCE和SFENCE 装载/储存,它们是弱有序的,并且绕过缓存。
如果这些链接死了,我的对另一个类似问题的回答中还有更多的信息。
https://stackoverflow.com/questions/19047327
复制相似问题