首页 > 解决方案 > MFENCE/LFENCE/SFENCE 函数内部的行为

问题描述

MFENCE / LFENCE / SFENCE指令作为内在的放在它意味着序列化的指令之前(A)与必须在需要序列化的指令之前调用的函数内的指令之间的行为有什么区别(B) ?

所以基本上之间的区别

(一个):

LFENCE
RDTSC

(乙):

Fence PROC
LFENCE
RET
Fence ENDP

...

CALL Fence
RDTSC

标签: assemblyx86x86-64intelinternals

解决方案


这取决于Fence函数中的确切内容。特别是,它取决于栅栏和rdtsc. 这也取决于之后的内容rdtsc

考虑这种lfence情况以及rdtsc定时区域顶部的位置。由于Fence正在使用该指令调用,因此该函数的末尾call可能有 a可以返回到以下. 这意味着在和之间至少有一个。这里很可能是 C3 的形式,它被解码并作为现代 Intel 和 AMD 处理器上的两个微指令分配到保留站。这些微指令用于从堆栈加载返回地址并验证预测,因此它们之间存在真正的数据依赖关系,并且当前处理器不使用值预测。retrdtscretlfencerdtscret

如果 L1D 和 DTLB 或 STLB 中的负载命中,或者如果值是从存储缓冲区转发的(这是可能的,因为lfence不等待存储缓冲区耗尽),那么两者之间不太可能存在差异lfence放置在两个指令之前rdtscret在两个指令之间有一个。但是,如果加载需要很长时间,rdtsc可能已经执行,后面的指令也会在后端进行中。加载完成后,RS 中还有一个ret等待执行的 uop from。此微指令会消耗某些资源,并且可能会干扰定时区域中的所有其他微指令,并可能影响测量时间。请注意,即使您的简单Fence函数,硬件中断可能发生在之前RET,使存储转发不可能,并可能最终从 L1D 中逐出返回地址。无论如何,除非您在定时区域中遇到病态指令序列,否则这无关紧要,除非您真的想要极高的精度。

您通常希望lfence立即放置在rdtsc. 如果可能,您可以使用宏而不是函数或强制编译器内联函数(但即便如此,您仍然必须检查生成的 asm 代码并确保它是您想要的)。

sfence不与retor交互rdtsc,因此对于这些指令没有排序效果。mfence强制负载ret等待,直到大多数早期与内存相关的操作达到全局可监督性或持久性点。mfence并且sfence单独不要序列化rdtsc


推荐阅读