我经常在互联网上发现LFENCE在x86处理器中毫无意义,也就是说,它什么也没有做,因此使用MFENCE绝对可以轻松使用SFENCE,因为MFENCE = SFENCE + LFENCE = SFENCE + NOP = SFENCE

但是,如果LFENCE没有意义,那么为什么我们有四种在x86 / x86_64中实现顺序一致性的方法:

  • LOAD(无围栏)和STORE + MFENCE
  • LOAD(无围栏)和LOCK XCHG
  • MFENCE + LOADSTORE(无围栏)
  • LOCK XADD(0)和STORE(无围栏)

  • 从这里拍摄:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

    以及底部第34页的Herb Sutter的表演:https://skydrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&wdo=2&authkey=!AMtj_EflYn2507c

    如果LFENCE没有执行任何操作,则方法(3)具有以下含义:SFENCE + LOAD and STORE (without fence),但是在SFENCE之前执行LOAD毫无意义。即,如果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刷新存储缓冲区。

    最佳答案

    底线(TL; DR):仅LFENCE确实对内存排序毫无用处,但是并不能使SFENCE代替MFENCE。问题中的“算术”逻辑不适用。

    这是Intel's Software Developers Manual, volume 3第8.2.2节(2014年9月的版本325384-052US)的摘录,与我在another answer中使用的相同



    从这里开始:

  • MFENCE是所有内存类型(无论是否为非临时性)上所有操作的完整内存防护。
  • SFENCE仅阻止对写入进行重新排序(换句话说,这是StoreStore的障碍),并且仅与非临时存储和其他列为异常的指令一起使用。
  • LFENCE可以防止对读取和后续读取和写入进行重新排序(即,它结合了LoadLoad和LoadStore屏障)。但是,前两个项目符号说LoadLoad和LoadStore障碍始终存在,没有异常(exception)。因此,仅LFENCE不能用于内存排序。

  • 为了支持最后一个要求,我查看了英特尔手册的所有3卷中提到LFENCE的所有地方,但没有发现会说LFENCE是内存一致性所必需的。甚至MOVNTDQA-迄今为止唯一的非时间加载指令-都提到了MFENCE,但没有提到LFENCE

    更新:查看Why is (or isn't?) SFENCE + LFENCE equivalent to MFENCE?上答案的正确答案,以查看
    MFENCE是否等于其他两个范围的“和”是一个棘手的问题。一眼看去,在这三个栅栏指令中,只有MFENCE提供了StoreLoad屏障,即防止使用较早的写入对读取进行重新排序。然而,正确的答案需要了解的不仅仅是上述规则;也就是说,重要的是所有栅栏指令都必须相对于彼此排序。这使SFENCE LFENCE序列比仅仅结合单个效果更强大:此序列还防止了StoreLoad重新排序(因为加载无法通过LFENCE,而不能通过SFENCE,而不能通过存储而无法通过),从而构成了完整的内存屏障(也请参见下面的注释(*))。但是请注意,这里的顺序很重要,并且LFENCE SFENCE序列没有相同的协同作用。

    但是,虽然可以说MFENCE ~ SFENCE LFENCELFENCE ~ NOP,但这并不意味着MFENCE ~ SFENCE。我故意使用等价(〜)而非等号(=)来强调算术规则不适用于此处。 SFENCELFENCE的互作用使两者有所不同。即使负载没有相互重新排序,也需要使用LFENCE来防止使用SFENCE对负载进行重新排序。

    (*)仍然可以说MFENCE比其他两个篱笆的组合要强。特别是,英特尔手册第2卷中的CLFLUSH指令说明说:“CLFLUSH仅由MFENCE指令排序。不能保证由任何其他防护或序列化指令或其他CLFLUSH指令排序。”

    (更新后,clflush现在被定义为严格排序的(就像普通商店一样,因此,如果您想阻止以后的加载,则只需要mfence即可),但是clflushopt的排序很弱,但是可以被sfence围起来。)

    关于assembly - 在x86/x86_64处理器上使用LFENCE指令有意义吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20316124/

    10-09 08:56