x86-64使用LFENCE

时间:2016-05-26 06:04:53

标签: assembly x86-64 cpu-architecture atomicity

我正在尝试了解使用RDTSC / RDTSCP测量时间时使用栅栏的正确方法。关于与此相关的SO的几个问题已经得到了精心解答。我经历了其中一些。我也经历过关于同一主题的这篇非常有用的文章: http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf

然而,在另一个在线博客中,有一个在x86上使用LFENCE而不是CPUID的例子。我想知道LFENCE如何阻止早期商店污染RDTSC测量。 E.g。

<Instr A>
LFENCE/CPUID
RDTSC
<Code to be benchmarked>
LFENCE/CPUID
RDTSC 

在上面的例子中,LFENCE确保它之前完成的所有早期加载(因为SDM说:LFENCE指令不能通过先前的读取。)。但是早期的商店呢(比如,Instr A是商店)?我理解为什么CPUID有效,因为它是一个序列化指令,但LFENCE不是。

我发现的一个解释是在英特尔SDM VOL 3A第8.3节中,以下脚注:

LFENCE确实为指令排序提供了一些保证。它在本地完成所有先前指令之前不会执行,并且在LFENCE完成之前没有后续指令开始执行。

所以LFENCE本质上就像一个MFENCE。在那种情况下,为什么我们需要两个单独的指令LFENCE和MFENCE?

我可能错过了一些东西。

提前致谢。

2 个答案:

答案 0 :(得分:6)

关键点是引用句子中的副词本地&#34; 直到所有先前的指示在本地完成后才会执行&#34;。

我无法找到&#34;在本地完成的明确定义&#34;整套英特尔手册,我的推测解释如下。

为了在本地完成,指令必须使其输出计算并且可用于其依赖链中的其他指令。 此外,该指令的任何副作用必须在核心内部可见。

为了全局完成,指令必须使其副作用对其他系统组件(如其他CPU)可见。

如果我们没有资格完成这种&#34;完整性&#34;我们在谈论它通常意味着它不关心或它隐含在上下文中。

对于在本地和全球范围内完成的大量说明,它是相同的 例如,对于 load ,为了在本地完成,必须从内存或缓存中获取一些数据。 这与全局完成相同,因为如果我们不首先从内存层次结构中读取,则无法标记负载完成。

对于商店但情况有所不同。

英特尔处理器有一个存储缓冲区来处理对内存的写入,从手册3的第11.10章开始:

  

Intel 64和IA-32处理器将每个写入(存储)临时存储到存储缓冲区中的内存中。商店缓冲区   通过允许处理器继续执行指令而不必执行来提高处理器性能   等到对内存和/或缓存的写入完成。它还允许延迟写入以便更有效地使用   内存访问总线周期。

因此,存储可以通过放入存储缓冲区在本地完成,从核心角度来看,写入就像它已经一直存储到存储器中。
在特定情况下,来自商店同一核心的负载甚至可以读回该值(这称为 Store Forwarding )。

要在全球范围内完成,商店需要从商店缓冲区耗尽

最后必须添加“存储缓冲区”通过序列化指令排除:

  

在以下情况下,存储缓冲区的内容总是耗尽到内存中:
  •(仅限P6和更新的处理器系列)执行序列化指令时   •(Pentium III,仅限更新的处理器系列)使用SFENCE指令订购商店时   •(仅限Pentium 4和更新的处理器系列)使用MFENCE指令订购商店时。

完成介绍后,让我们看看lfencemfencesfence做了什么:

  

LFENCE在本地完成所有先前指令之前不会执行,并且在LFENCE完成之前没有后续指令开始执行。

     

MFENCE对在MFENCE指令之前发出的所有内存加载和存储到内存指令执行序列化操作。   MFENCE不会序列化指令流。

     

SFENCE对SFENCE指令之前发出的所有存储到存储器指令执行序列化操作。

所以lfence是较弱的序列化形式,不会耗尽存储缓冲区,因为它有效地在本地序列化指令,所有负载必须在它完成之前完成。

sfence仅序列化商店,它基本上不允许进程再次执行商店,直到sfence退出。它还会耗尽Store缓冲区。

mfence 是两者的简单组合,因为它不是经典意义上的序列化,它是sfence,也可以阻止将来的加载执行。

首先引入sfence并且之后的其他两个版本对内存排序进行更精细的控制可能毫无价值。

最后,我习惯在两条rdtsc指令之间关闭lfence指令,以确保没有重新排序&#34;向后&#34;和&#34;前进&#34;是可能的。
但是我确信这种技术合理。

答案 1 :(得分:1)

正如您所理解的那样,这是序列化的问题。关于你的问题

  

为什么我们需要两个单独的指令LFENCE和MFENCE?

Intel SDM部分&#34; 5.6.4中得到解答 - SSE2可缓存性控制和订购说明&#34;:

  

LFENCE序列化加载操作
  MFENCE序列化加载和存储操作

因此可能会使用LFENCE,因为MFENCE不需要RDTSC