Intel的SFENCE指令具有发布语义吗?

16
似乎 "Acquire" 和 "Release" 语义的公认定义是这样的: (摘自 http://msdn.microsoft.com/en-us/library/windows/hardware/ff540496(v=vs.85).aspx)
一个操作具有“acquire”语义,如果其他处理器在任何后续操作之前总是看到它的效果。一个操作具有“release”语义,如果其他处理器在其自身生效之前看到每个先前操作的效果。
我简要阅读了存在一半内存屏障的例子,据说它们呈现“acquire barriers”和“release barriers”的形式,遵循上述相同的语义。
在查找实际硬件指令的示例时,我遇到了 SFENCE。而这篇博客 (http://peeterjoot.wordpress.com/2009/12/04/intel-memory-ordering-fence-instructions-and-atomic-operations/) 表示,它是释放式屏障/障碍的一种形式:
Intel 提供了双向屏障指令 MFENCE,acquire 屏障指令 LFENCE 和 release 屏障指令 SFENCE。
然而,阅读 SFENCE 的定义,它似乎并未提供 release 语义,因为它根本不与 load 同步?而我理解的“release”语义是相对于所有内存操作(load 和 store)的顺序定义。
1个回答

20
LFENCE没有获取语义;SFENCE没有释放语义。这是有道理的:拥有独立的获取或释放语义的栅栏指令几乎是没有用的。要使获取或释放有用,它必须与内存操作相关联。
例如,考虑在两个线程之间发送数据的常见模式:
1. 处理器A写入缓冲区。 2. 处理器A向标志写入“true”。 3. 处理器B等待标志为真。 4. 处理器B读取缓冲区。
请注意,处理器A必须确保在写入标志后,其写入缓冲区被看到。现在假设我们有一个名为“RFENCE”的释放栅栏指令。如果我们将该指令放在步骤(1)之后,它是没有用的,因为步骤(2)中的写入允许出现在RFENCE上方并通过步骤(1)上方。
类似的论点表明,“AFENCE”执行获取同样对于确保步骤3中标志的读取不会出现在步骤4下面是无用的。
Itanium通过提供写入释放和加载获取指令来优雅地解决了这个问题,并将栅栏与内存操作绑定。
回到IA-32和Intel64:如果程序不使用“非临时”指令,则剩余指令的行为就像每个加载都进行“获取”和每个存储都进行“释放”。请参阅Intel® 64和IA-32体系结构开发人员手册:Vol. 3A第8.2.3节(和子节)。如果涉及“非临时”存储,则有几种方法可强制执行栅栏:
- 使用SFENCE - 使用MFENCE - 有点过度杀伤
  • 使用LOCK前缀指令(例如“LOCK INC”)来写入标志。 LOCK前缀的指令隐含具有MFENCE。
  • 使用XCHG来写入标志,它的作用就像具有隐含LOCK前缀一样。
  • 例如,如果在早期的习惯用法中,使用非临时存储器存储缓冲区,则处理器A在步骤1和2之间发出SFENCE或MFENCE。 或者使用XCHG来写入标志。

    所有以上内容均适用于硬件。 在使用高级语言时,请确保编译器不会破坏事件的关键排序。 C++11原子操作库存在是为了让您能够告诉编译器硬件您的意图。


    例如,如果在先前的惯用语中,缓冲区是使用非临时存储器写入的,则应在步骤1和2之间让处理器B发出SFENCE或MFENCE。或者使用XCHG来写入标志。- 我认为你指的是处理器A而不是B - Stuart Gillibrand
    1
    @StuartGillibrand:感谢您发现错误。我已经更正了,并更正了一个错误的“it's”->“its”。 - Arch D. Robison
    2
    你说得没错,SFENCE确实没有释放语义;然而,根据你引用的手册§8.2.2的定义,LFENCE至少提供了获取(LoadLoad + LoadStore)语义。在比x86更弱一致性模型的架构中,确实需要使用独立于障碍物的屏障来确保一致性,例如SPARC-V9的membar #LoadLoad | #LoadStore(用于获取)和membar #LoadStore | #StoreStore(用于释放)。虽然获取和释放语义应该与任何内存操作相关才能有用,但这并不意味着这样的屏障没有任何用处。 - minmaxavg
    澄清一下,在你的术语中,这些屏障应该被认为是“绑定”到相关指令的,这些指令要么在执行顺序中先于它们,要么在之后。一个load-acquire操作等同于先load再acquire barrier(确切地按照这个顺序),而一个store-release操作可以用release barrier后跟store来替代。任何对这个主题感兴趣的人也可能会发现这个答案有帮助:https://dev59.com/mGEh5IYBdhLWcg3wtFX4#22142537。 - minmaxavg

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接