我可以使用四个通用寄存器(例如 r8、r9、r10、r11),每个寄存器都带有 MOV 指令来进行独立操作,并感觉 CPU 在单个时钟中执行所有这些指令吗?
我想知道,因为根据Agner Fog的指令表,它说MOV指令的倒数吞吐量是0.25。这意味着 CPU 每个周期应该能够执行 4 个 MOV 操作。或者我误解了这一切??
我是一个菜鸟,两个月以来一直在 MASM 中学习汇编(主要是为了学习调试寄存器如何工作的东西,这真的很有趣)。
最佳答案
编辑,只需重新阅读您的问题,您正在询问不同的寄存器。我将保留原来的答案;让我们假设你的问题不仅仅是最微不足道的案例。 :P
是的,即使没有寄存器重命名,这些指令也可以在同一周期中执行(在单独的执行单元上),因为它们彼此完全独立。
mov eax, 1
mov ebx, ecx
mov edx, [mem]
xor esi,esi ;xor-zero: doesn't even use an execution unit on SnB-family
这是超标量执行最简单的情况。如果 eax/rax 是所有四个指令的目标,寄存器重命名仍然允许所有四个指令并行执行。
乱序执行允许来自不同依赖链的四个附近指令同时执行,即使它们不是在同一时钟周期内解码或发出的。如果他们之间有指示的话,他们也可能不会在同一周期退休。 (x86 ISA 保证精确的异常,就像大多数其他 ISA(ARM/PPC/等)一样。所有当前的设计都是按顺序退休完成的。因此,如果内存操作出现段错误,程序将准确地停止在该指令处,而不仅仅是“好吧,最近某处出现了段错误,但我们无法告诉您在哪里”。(这将是不精确的异常(exception))。)
像 Atom 或 P5(原始 Pentium)这样的超标量有序设计仍然可以利用这四个独立指令中的并行性,但在许多其他情况下则不然。
在手工制作的循环中,SnB 系列 CPU 通常能够在每个周期维持超过 3 个融合域微指令。 (由于延迟,编写每个周期运行少于一个融合域 uop 的循环也很容易,更不用说缓存未命中或分支错误预测了。)
是的,对同一架构寄存器的多次写入可以并行执行。寄存器重命名不是 Intel 或 AMD 设计的瓶颈。
要理解并充分利用 Agner Fog 的表格,您必须阅读 his microarch guide, or at least his "optimizing assembly" guide 。另请参阅 x86 上的好东西维基百科。
正如 Agner Fog 的 microarch pdf 指出的那样(有关英特尔 SnB/IvB 的第 9.8 节):
Register renaming is controlled by the register alias table (RAT) and the reorder buffer (ROB), shown in figure 6.1. The μops from the decoders and the stack engine go to the RAT via a queue and then to the ROB-read and the reservation station. The RAT can handle 4 μops per clock cycle. The RAT can rename four registers per clock cycle, and it can even rename the same register four times in one clock cycle.
读取-修改-写入是另一个故事(add
指令的目标)。架构寄存器的读取-修改-写入是依赖链(的一部分),而无条件 mov 或异或归零则启动新的依赖链。 (某些其他指令的输出相同,例如 lea
,它们不读取其目的地)。
这些寄存器写入仍然将架构寄存器重命名为新的物理寄存器。这就是 CPU 处理类似情况的方式
mov eax, 1 ; start of a dep chain
mov [mem+rax+rcx], eax
inc eax ; eax renamed again
存储需要 inc
之前的 eax 值。它得到它是因为当它检查 RAT 时,架构 eax 仍然指向 mov eax,1
写入的同一物理寄存器。 inc
不能只修改同一个物理寄存器,因为它不知道如果尚未对 eax
的先前值执行任何操作,会发生什么。
关于performance - 每个时钟性能。 - 我可以对同一条指令使用不同的寄存器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35715324/