如果同一个寄存器分别作为输入和输出,两条指令是否可以在同一个周期内执行?
Can two instructions execute in the same cycle if the same register is used as input and output respectively?
例如,这两条指令是在同一个周期开始执行还是相互干扰?
MOV %RAX, (ADDR) # AT&T syntax: store rax
POP %RAX
是的,他们可以在现代乱序CPU上在同一个周期执行,因为他们使用Tomasulo's algorithm for register renaming. It totally avoids all write-after-read hazards like this, and also write-after-write,所以乱序执行只受限于Read- after-Write 真正的依赖关系。
寄存器重命名后,pop
会将 RAX 架构寄存器的新值写入与保存 RAX 旧值(作为存储的输入)的物理寄存器不同的物理寄存器。
指令之间的交互为零,因为 pop
为 RAX 的值启动了一个新的依赖链。 (它的输出是只写的。)pop
(以及 read/write RAX 的后续指令)可以在存储之前执行许多周期,尤其是在生成要存储的值的情况下通过长依赖链。
另请参阅 Agner Fog's microarch pdf and other links in the x86 标签 wiki。
更新:我以为你问的是两条指令写同一个寄存器或读同一个寄存器,因为你原来的示例代码没有 %
标记,并使用了 AX,所以我认为它是16 位 Intel 语法。无论如何留下这部分作为奖励。
读取同一个寄存器的两条指令(读取后读取)根本不是危险。
Intel CPUs before Sandybridge 对同一个周期内可以读取的最近未修改的寄存器的数量有限制,但是在附近的指令中多次读取同一个寄存器是没有问题的. (在 Agner Fog 的 microarch pdf 中搜索寄存器读取端口停顿,and/or 参见 )。
例如,这两条指令是在同一个周期开始执行还是相互干扰?
MOV %RAX, (ADDR) # AT&T syntax: store rax
POP %RAX
是的,他们可以在现代乱序CPU上在同一个周期执行,因为他们使用Tomasulo's algorithm for register renaming. It totally avoids all write-after-read hazards like this, and also write-after-write,所以乱序执行只受限于Read- after-Write 真正的依赖关系。
寄存器重命名后,pop
会将 RAX 架构寄存器的新值写入与保存 RAX 旧值(作为存储的输入)的物理寄存器不同的物理寄存器。
指令之间的交互为零,因为 pop
为 RAX 的值启动了一个新的依赖链。 (它的输出是只写的。)pop
(以及 read/write RAX 的后续指令)可以在存储之前执行许多周期,尤其是在生成要存储的值的情况下通过长依赖链。
另请参阅 Agner Fog's microarch pdf and other links in the x86 标签 wiki。
更新:我以为你问的是两条指令写同一个寄存器或读同一个寄存器,因为你原来的示例代码没有 %
标记,并使用了 AX,所以我认为它是16 位 Intel 语法。无论如何留下这部分作为奖励。
读取同一个寄存器的两条指令(读取后读取)根本不是危险。
Intel CPUs before Sandybridge 对同一个周期内可以读取的最近未修改的寄存器的数量有限制,但是在附近的指令中多次读取同一个寄存器是没有问题的. (在 Agner Fog 的 microarch pdf 中搜索寄存器读取端口停顿,and/or 参见