在互联网上经常看到说x86处理器中的LFENCE
无意义,即它什么也不做,所以我们可以代替使用MFENCE
来绝对无痛地使用SFENCE
,因为MFENCE
=SFENCE
+LFENCE
=SFENCE
+NOP
=SFENCE
。
但是,如果LFENCE
没有意义,那么为什么我们有四种方法在x86/x86_64中实现顺序一致性:
LOAD
(没有栅栏)和STORE
+MFENCE
LOAD
(没有栅栏)和LOCK XCHG
MFENCE
+LOAD
和STORE
(没有栅栏)LOCK XADD
(0)和STORE
(没有栅栏)
摘自此处:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
以及Herb Sutter在第34页底部的表演:https://skydrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&wdo=2&authkey=!AMtj_EflYn2507c
如果LFENCE
什么也不做,那么方法(3)会有以下含义:SFENCE + LOAD和STORE(没有栅栏)
,但在执行LOAD
之前执行SFENCE
是没有意义的。也就是说,如果LFENCE
什么也不做,则方法(3)没有意义。
在x86/x86_64处理器中,LFENCE
指令是否有意义?
回答:
1. 在下面的被接受的答案中描述的情况下,需要使用LFENCE
。
2. 应该将方法(3)作为前面命令的组合来考虑,而不是独立地看待。例如,方法(3):
MFENCE
MOV reg, [addr1] // LOAD-1
MOV [addr2], reg //STORE-1
MFENCE
MOV reg, [addr1] // LOAD-2
MOV [addr2], reg //STORE-2
我们可以将方法(3)的代码重写如下:
SFENCE
MOV reg, [addr1] // LOAD-1
MOV [addr2], reg //STORE-1
SFENCE
MOV reg, [addr1] // LOAD-2
MOV [addr2], reg //STORE-2
这里SFENCE
的作用是防止STORE-1和LOAD-2的重排序。因此,在STORE-1命令之后,SFENCE
将清空存储缓冲区。