用于订购rdtsc。lfence如果您不需要等待存储缓冲区耗尽,其他指令就足够了。自从一直使用 Intel 以来,自从 Spectre 缓解针对 AMD以来。查看rdtsc 乱序执行的解决方案?
rdtscp也保证按 wrt 订购。较早的指令(但不是较晚的指令;实际上,它的微编码可能非常类似于lfence;rdtsc按此顺序,再加上用处理器 ID 写入 ECX 的微指令。)它不是 x86 序列化指令,甚至不会耗尽存储缓冲区。(无论如何,你不一定想要计时。)你可以mfence; rdtscp或者lock or byte [rsp], 0 ; rdtscp如果你想要的话,或者rdtscp; lfence如果你想确保它的几个微指令不能与以后的东西重新排序。
另请参阅此问答,了解有关 TSC 的更多一般信息,它是固定频率,而不是 CPU 周期。
为了回答标题中关于 x86 技术术语意义上的“序列化指令”的问题,
Alder Lake(和 Sapphire Rapids)以及后来的serialize,它确实做到了这一点,仅此而已。
lfence序列化指令执行(耗尽 ROB 但不存储缓冲区或前端):请参阅
在虚拟机中,cpuid是有保证的 vmexit,所以速度很慢。推送 RSP、RFLAGS、CS 和 RIP 并运行指令可能会更快iret。我没有仔细检查 iret 弹出的内容,因此可能不完全正确。
交叉修改代码是一种正确的序列化指令与类似的指令相比很重要的情况mfence;lfence。在获取加载看到表明新代码存在的发布存储后,您需要运行序列化指令。英特尔第 3 卷手册第 8.1.3 节保证了交叉修改代码的安全性。
我认为这可以确保前端尚未获取旧代码。因此,序列化指令可能会完全破坏管道,或者如果对管道中的最近指令有足够的跟踪来窥探 L1i 失效,则可以执行等效操作。(这种额外的窥探可能不值得,因为序列化指令很少见。无论如何,都需要跟踪来处理自修改代码,窥探存储地址以接近任何正在运行的指令。)
mfence(或lock or byte [rsp],0)+lfence不一定足够强大,因为lfence仅耗尽 ROB,涉及指令执行而不是获取,并mfence处理数据加载/存储。 cpuid如果您不能使用 ,那么对于这种情况来说是一个不错的选择serialize。
(即使是编写器中对齐的 8 字节块内的原子 RMW 或原子存储也是不够的。在某些微体系结构上,我认为从 L1i 缓存中未对齐地提取 16 字节块的代码是可能的,因此读者可能会大吃一惊任何边界。)
| 归档时间: |
|
| 查看次数: |
1317 次 |
| 最近记录: |