编辑,重新阅读你的问题,你问的是不同的寄存器。我会留下我原来的答案;让我们假设您的问题不仅仅是最微不足道的案例。 :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/等)一样。所有当前的设计都通过按顺序退休来完成。因此,如果内存操作段错误,程序将完全停止在该指令处,而不仅仅是“好吧,最近某个地方出现了段错误,但我们不能告诉你在哪里”。(那将是不精确的例外)。)
像 Atom 或 P5(原始 Pentium)这样的超标量有序设计仍然可以利用这四个独立指令中的并行性,但在许多其他情况下却不行。
在手工制作的循环中,SnB 系列 CPU 在每个循环中能够维持超过 3 个融合域微指令是很常见的。 (由于延迟,更不用说缓存未命中或分支错误预测,编写每个周期运行少于一个融合域 uop 的循环也很容易。)
是的,对同一个架构寄存器的多次写入可以并行执行。寄存器重命名不是 Intel 或 AMD 设计的瓶颈。
要了解和充分利用 Agner Fog 的表格,您必须阅读 his microarch guide, or at least his "optimizing assembly" guide。另请参阅 x86 wiki 上的好东西。
正如 Agner Fog 的 microarch pdf 指出的那样(第 9.8 节关于英特尔 SnB/IvB):
寄存器重命名由寄存器别名表 (RAT) 控制,并且
重新排序缓冲区 (ROB),如图 6.1 所示。 μops 来自
解码器和堆栈引擎通过队列进入 RAT,然后
ROB-read 和预约站。 RAT 可以处理 4 μops
每个时钟周期。 RAT 可以在每个时钟周期重命名四个寄存器,
它甚至可以在一个时钟内重命名同一个寄存器四次
循环。
read-modify-write 是另一回事(add 指令的目标)。架构寄存器的读-修改-写是依赖链的(一部分),而无条件的mov 或异或置零会启动一个新的 dep 链。 (对于某些其他指令的输出也是如此,例如 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 还没有完成任何事情会怎样。