障碍不会造成
其他
线程/核心等待。他们在当前线程中执行一些操作
屏障甚至不会让其他线程更快地看到您的加载/存储;CPU核心已经尽可能快地将存储缓冲区中的存储提交(失效)到L1d缓存。(在遵循了所有必要的MESI一致性规则之后,x86的强内存模型只允许存储按程序顺序提交,即使没有障碍)。
障碍不一定有序
,他们命令
全球知名度
mfence
(或
lock
ed operation
喜欢
lock add
或
xchg [mem], reg
线程等待所有以前的加载和存储完成并全局可见(即刷新存储缓冲区)。
使用全栅障
不
Are loads and stores the only instructions that gets reordered?
详细情况。但是
锁
ed操作和
xchg
不是那样的;它们是完全的记忆障碍,但它们仍然允许无序执行
imul eax, edx
对于超线程,我认为这种暂停发生在每个逻辑线程上,而不是整个内核上。
但请注意
使用全栅障
手动输入并不能说明如何暂停核心,所以未来的x86实现可以自由地提高它的效率(比如
lock or dword [rsp], 0
sfence
只有在航班上有新台币商店的情况下才能做任何事情。它根本不命令加载,因此不必停止以后的指令执行。见
Why is (or isn't?) SFENCE + LFENCE equivalent to MFENCE?
.
斯芬斯
屏障可以离开存储缓冲区。(即写合并缓冲区必须刷新)。但在到达存储缓冲区的末尾之前,它可能已经从核心的无序执行部分(ROB或ReOrder缓冲区)中退出
Does a memory barrier ensure that the cache coherence has been completed?
lfence
因为记忆障碍几乎是无用的:它只能阻止
movntdqa
从WC内存中加载,通过以后的加载/存储进行重新排序。你几乎不需要那个。
的实际用例
lfence公司
lfence; rdtsc
在英特尔CPU上,您可以避免
rdtsc
把时钟读得太早,作为一种更便宜的替代方法
cpuid; rdtsc
)
最近的另一个重要用例
lfence公司
是阻止推测性执行(例如,在条件或间接分支之前),以减轻幽灵的影响。这完全基于其部分序列化的英特尔保证的副作用,与其LoadLoad+LoadStore屏障效应无关。
lfence公司
做
必须等待存储缓冲区耗尽,然后才能从ROB中退出,因此LFENCE+SFENCE的组合没有MFENCE强。
Why is (or isn't?) SFENCE + LFENCE equivalent to MFENCE?
相关:
When should I use _mm_sfence _mm_lfence and _mm_mfence
(用C++代替ASM编写时)。
请注意,C++的本质类似
_mm_sfence
也阻止编译时内存排序。这通常是必要的,即使当ASM指令本身不是,因为C++编译时重新排序是基于C++的非常弱的内存模型,而不是强的x86内存模型,它适用于编译器生成的ASM。
所以
_嗯哼
可能会让你的代码工作,但除非你使用NT存储,否则这是过分的。一个更有效的选择是
std::atomic_thread_fence(std::memory_order_release)
http://preshing.com/20120625/memory-ordering-at-compile-time/
.