assembly - MFENCE/LFENCE/SFENCE 函数内部的行为
问题描述
MFENCE / LFENCE / SFENCE指令作为内在的放在它意味着序列化的指令之前(A)与必须在需要序列化的指令之前调用的函数内的指令之间的行为有什么区别(B) ?
所以基本上之间的区别
(一个):
LFENCE
RDTSC
(乙):
Fence PROC
LFENCE
RET
Fence ENDP
...
CALL Fence
RDTSC
解决方案
这取决于Fence
函数中的确切内容。特别是,它取决于栅栏和rdtsc
. 这也取决于之后的内容rdtsc
。
考虑这种lfence
情况以及rdtsc
定时区域顶部的位置。由于Fence
正在使用该指令调用,因此该函数的末尾call
可能有 a可以返回到以下. 这意味着在和之间至少有一个。这里很可能是 C3 的形式,它被解码并作为现代 Intel 和 AMD 处理器上的两个微指令分配到保留站。这些微指令用于从堆栈加载返回地址并验证预测,因此它们之间存在真正的数据依赖关系,并且当前处理器不使用值预测。ret
rdtsc
ret
lfence
rdtsc
ret
如果 L1D 和 DTLB 或 STLB 中的负载命中,或者如果值是从存储缓冲区转发的(这是可能的,因为lfence
不等待存储缓冲区耗尽),那么两者之间不太可能存在差异lfence
放置在两个指令之前rdtsc
并ret
在两个指令之间有一个。但是,如果加载需要很长时间,rdtsc
可能已经执行,后面的指令也会在后端进行中。加载完成后,RS 中还有一个ret
等待执行的 uop from。此微指令会消耗某些资源,并且可能会干扰定时区域中的所有其他微指令,并可能影响测量时间。请注意,即使您的简单Fence
函数,硬件中断可能发生在之前RET
,使存储转发不可能,并可能最终从 L1D 中逐出返回地址。无论如何,除非您在定时区域中遇到病态指令序列,否则这无关紧要,除非您真的想要极高的精度。
您通常希望lfence
立即放置在rdtsc
. 如果可能,您可以使用宏而不是函数或强制编译器内联函数(但即便如此,您仍然必须检查生成的 asm 代码并确保它是您想要的)。
sfence
不与ret
or交互rdtsc
,因此对于这些指令没有排序效果。mfence
强制负载ret
等待,直到大多数早期与内存相关的操作达到全局可监督性或持久性点。mfence
并且sfence
单独不要序列化rdtsc
。
推荐阅读
- android - 约束布局切掉了我的一些观点
- javascript - 使用 Webpack 捆绑老式的串联 JS
- graphql - What is the idiomatic graphql way to use fields that depends on other nodes?
- sql - ORA-00905: 缺少关键字(从教科书复制)
- node.js - 使用车把助手检测两个日期是否匹配
- php - 在 laravel 项目中运行“laravel new”命令
- python - 我需要创建一个编号为 = 0000 的票,并且每次执行代码时它应该增加 1
- python-3.x - giving arguements to a function without calling it in tkinter
- r - Running bootstrap on Total Least Squares Regression coefficent
- foursquare - 查询 Foursquare 场所时收到 invalid_authentication 错误