是否有比cpuid更便宜的序列化指令?

mer*_*011 2 intel rdtsc cpu-cache

我已经看到了相关的问题,包括这里这里,但似乎有关序列化的唯一指令rdtsccpuid.

不幸的是,cpuid我的系统需要大约1000个周期,所以我想知道是否有人知道更便宜(更少的周期和没有读或写内存)序列化指令?

我看着iret,但这似乎改变了控制流程,这也是不可取的.

我实际上看过亚历克斯的答案中关联的白纸rstscp,但它说:

在读取计数器之前,RDTSCP指令等待直到执行了所有先前的指令.然而,后续指令可以在执行读取操作之前开始执行.

第二点似乎是让它不理想.

Ale*_*rle 8

你看过这个rdtscp指令了吗?这是读取的序列化版本rdtsc.

对于基准测试,我建议阅读本白皮书.它提供了几种测量时钟滴答的最佳实践.

亚历克斯(英特尔)


Pet*_*des 5

用于订购rdtsclfence如果您不需要等待存储缓冲区耗尽,其他指令就足够了。自从一直使用 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 弹出的内​​容,因此可能不完全正确。


当您需要真正的序列化指令时

交叉修改代码是一种正确的序列化指令与类似的指令相比很重要的情况mfencelfence。在获取加载看到表明新代码存在的发布存储后,您需要运行序列化指令。英特尔第 3 卷手册第 8.1.3 节保证了交叉修改代码的安全性。

我认为这可以确保前端尚未获取旧代码。因此,序列化指令可能会完全破坏管道,或者如果对管道中的最近指令有足够的跟踪来窥探 L1i 失效,则可以执行等效操作。(这种额外的窥探可能不值得,因为序列化指令很少见。无论如何,都需要跟踪来处理修改代码,窥探存储地址以接近任何正在运行的指令。)

mfence(或lock or byte [rsp],0)+lfence不一定足够强大,因为lfence仅耗尽 ROB,涉及指令执行而不是获取,并mfence处理数据加载/存储。 cpuid如果您不能使用 ,那么对于这种情况来说是一个不错的选择serialize

(即使是编写器中对齐的 8 字节块内的原子 RMW 或原子存储也是不够的。在某些微体系结构上,我认为从 L1i 缓存中未对齐地提取 16 字节块的代码是可能的,因此读者可能会大吃一惊任何边界。)


归档时间:

查看次数:

1317 次

最近记录:

11 年,3 月 前