performance - 每个时钟性能。 - 我可以对同一条指令使用不同的寄存器吗?

标签 performance assembly cpu-registers clock

我可以使用四个通用寄存器(例如 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 。另请参阅 上的好东西维基百科。

正如 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/

相关文章:

android - 如何加速 Flex Mobile 并提高其性能

assembly - 什么是 callq 指令?

c - 在现代 64 位 Linux 中将 C 函数库链接到 x86 汇编程序

c - 内联汇编 - 无用的中间复制指令

performance - 使用 Docker 对简单的 Go 服务器造成巨大的性能影响

c# - 应该重写代码还是应该使用方法?

assembly - 对齐节的开头是什么意思?

jvm - 为什么JVM是基于堆栈的而Dalvik VM是基于寄存器的?

.net - SqlBulkCopy 的建议批量大小是多少?