assembly - 如果使用同一个寄存器分别作为输入和输出,两条指令能否在同一个周期内执行?

标签 assembly x86 x86-64 cpu-architecture micro-optimization

例如,这两条指令是在同一个周期内开始执行还是相互干扰?

MOV  %RAX, (ADDR)      # AT&T syntax: store rax
POP  %RAX

最佳答案

是的,它们可以在现代乱序 CPU 上以相同周期执行,因为它们使用 Tomasulo's algorithm用于寄存器重命名。它完全避免了所有 write-after-read hazards like this, and also write-after-write ,因此乱序执行仅受 Read-after-Write 真正依赖项的限制。

寄存器重命名后,pop将 RAX 架构寄存器的新值写入与保存 RAX 旧值的物理寄存器不同的物理寄存器(作为存储的输入)。

指令之间的交互为零,因为 pop为 RAX 的值启动一个新的依赖链。 (它的输出是只写的。) pop (以及跟随读/写 RAX 的指令)可以在存储之前执行多个周期,特别是如果要存储的值是由长依赖链产生的。

另见 Agner Fog's microarch pdf以及 中的其他链接标记维基。

更新:我以为您是在询问写入相同寄存器或读取相同寄存器的两条指令,因为您的原始示例代码忽略了 %标记,并使用 AX,所以我假设它是 16 位 Intel 语法。无论如何,留下这部分作为奖励。

两条指令读取同一个寄存器(读后读)甚至根本没有危险。

Sandybridge 之前的 Intel CPU 对同一周期内可以读取的未最近修改的寄存器数量有限制,但在附近指令中多次读取同一寄存器不是问题。 (在 Agner Fog 的 microarch pdf 中搜索寄存器读取端口停顿,和/或查看 this answer where it was relevant)。

关于assembly - 如果使用同一个寄存器分别作为输入和输出,两条指令能否在同一个周期内执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39115935/

相关文章:

linux - 在 linux x86_64 程序集中生成一个 shell

c - SGABIOS 编译错误

gcc - 如何在GCC内联汇编中的Intel x86_64寄存器r8至r15上指定寄存器约束?

c - 使用 SSE/AVX 并行化 C 代码

assembly - 如何在 MASM 中编写远绝对 JMP/CALL 指令?

c - 由 8x __m256i 寄存器表示的矩阵的 AVX2 转置

c++ - 性能 32 位与 64 位算术

visual-studio - Visual Studio 中的外部程序集文件

linux - IA 32 读取命令行参数

assembly - 8086/8088 上的有效地址计算时间