首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >x86-64使用LFENCE

x86-64使用LFENCE
EN

Stack Overflow用户
提问于 2016-05-26 06:04:53
回答 2查看 2.3K关注 0票数 6

我试图理解使用RDTSC/RDTSCP测量时间时使用栅栏的正确方法。与此相关的几个问题已经得到了详尽的回答。我已经经历过几次了。我还阅读了这篇关于同一主题的非常有用的文章: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度量。例如。

代码语言:javascript
复制
<Instr A>
LFENCE/CPUID
RDTSC
<Code to be benchmarked>
LFENCE/CPUID
RDTSC 

在上述情况下,LFENCE确保它之前完成的所有早期加载(因为SDM说: LFENCE指令不能传递更早的读取。)但是早期的商店(比如说,Instr A是一家商店)呢?我理解为什么CPUID工作,因为它是一个序列化指令,但LFENCE不是。

我发现的一个解释是英特尔SDM第3A卷第8.3节,脚注如下:

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

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

我可能漏掉了什么。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-26 19:34:13

关键是引句中的副词,“在所有先前的指令都在本地完成之前,它不会执行”。

我找不到一个明确的定义“完全本地”的整套英特尔手册,我的猜测解释如下。

为了在本地完成,一条指令必须被计算出来并提供给依赖链中的其他指令。此外,该指令的任何副作用必须在核心内可见。

为了在全球范围内完成指令,它的副作用必须对其他系统组件(如其他CPU)可见。

如果我们不限定我们所谈论的那种“完整性”,通常意味着它不在乎,或者它在上下文中是隐含的。

对于许多在本地和全球都在完成的指令,这是一样的。

例如,为了在本地完成负载,必须从内存或缓存中获取一些数据。这与全局完成相同,因为如果不先从内存层次结构读取,则无法标记完成的加载。

然而,对于一家商店来说,情况就不同了。

Intel处理器有一个存储缓冲区来处理对内存的写操作,来自手册3的第11.10章:

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

因此,通过将存储放在存储缓冲区中,可以在本地完成存储,从核心角度看,写就像一直到内存中一样。

在特定情况下,来自同一存储核心的负载甚至可以读取该值(这称为存储转发)。

然而,要在全球范围内完成存储,需要从store缓冲区中提取存储。

最后,必须通过序列化指令来添加存储缓冲区:

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

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

在所有先前的指令在本地完成之前,LFENCE不会执行,在LFENCE完成之前,以后的指令也不会开始执行。MFENCE对在MFENCE指令之前发出的所有从内存加载和存储到内存的指令执行序列化操作.MFENCE不序列化指令流。 SFENCE对在SFENCE指令之前发出的所有存储到内存指令执行序列化操作.

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

sfence只序列化存储,在sfence退出之前,基本上不允许进程再执行任何存储。它还耗尽了存储缓冲区。

mfence而不是--这是两个简单的组合,因为它不是传统意义上的序列化,它也是一个sfence,它也阻止了将来的负载被执行。

sfence首先被引入,而其他两个则是为了实现对内存顺序的更细粒度的控制,这可能毫无价值。

最后,我习惯于关闭两个rdtsc指令之间的一个lfence指令,以确保不可能重新排序“向后”和“前进”。

不过,我确信这种技术是可靠的。

票数 12
EN

Stack Overflow用户

发布于 2016-05-26 14:04:37

正如您正确地看到的,这是一个序列化的问题。关于你的问题

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

英特尔SDM中的"5.6.4 - SSE2缓存控制和排序指令“部分中回答:

序列化负载操作 序列化加载和存储操作

所以使用LFENCE可能是因为MFENCE对于RDTSC来说不是必需的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37452772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档