gpt4 book ai didi

performance - 某些通用寄存器是否比其他寄存器更快?

转载 作者:行者123 更新时间:2023-12-03 15:45:21 25 4
gpt4 key购买 nike

在 x86-64 中,如果某些通用寄存器比其他寄存器更受欢迎,某些指令会执行得更快吗?
例如,会 mov eax, ecx执行速度快于 mov r8d, ecx ?我可以想象后者需要一个 REX 前缀,这会使指令获取速度变慢?
使用 rax 怎么样?而不是 rcx ?怎么样addxor ?其他操作?较小的寄存器,如 r15b对比 al ? al对比 ah ?
AMD VS 英特尔?较新的处理器?旧处理器?指令组合?
澄清:某些通用寄存器是否应该优先于其他寄存器,它们是哪些?

最佳答案

一般来说,架构寄存器都是相同的,并重命名为大量物理寄存器。
(除了部分寄存器可能会更慢,尤其是高字节 AH/BH/CH/DH,在写入完整寄存器后读取速度很慢,在 Haswell 和更高版本上。请参阅 How exactly do partial registers on Haswell/Skylake perform? Writing AL seems to have a false dependency on RAX, and AH is inconsistentWhy doesn't GCC use partial registers? 以了解写入 8 位和 16 位时的问题位寄存器)。这个答案的其余部分将只考虑 32/64 位操作数大小。)
但是某些指令需要特定的寄存器,例如传统的可变计数移位(没有 BMI2 shrx 等)需要 CL 中的计数。除法要求 EDX:EAX 中的被除数(对于较慢的 64 位版本,或 RDX:RAX)。
使用像 RBX 这样的调用保留寄存器意味着你的函数必须花费额外的指令来保存/恢复它。
但是,如果您需要更多说明,当然会有性能差异。因此,让我们假设所有其他条件都相同,只需通过更改用于其操作数的寄存器来讨论单个指令的 uops、延迟和代码大小。 TL:DR:唯一的性能差异是由于指令编码限制/差异。 有时不同的寄存器将允许/要求(或让汇编程序选择)不同的编码,作为特殊情况,通常会更小/更大,有时甚至以不同的方式执行。
通常,较小的代码速度更快,并且在 uop 缓存和 I-cache 中的打包效果更好,因此除非您分析了特定情况并发现了问题,否则最好使用较小的编码。通常这意味着在 AL 中保留一个字节值,以便您可以使用这些特殊情况指令,并避免使用 RBP/R13 作为指针。

特定编码特别慢的特殊情况,而不仅仅是大小
如果寻址模式还没有 +displacement 常量,以 RBP 或 R13 作为基础的 LEA 在 Intel 上可能会更慢。
例如lea eax, [rbp + 12] 可按原样编码,并且与 lea eax, [rcx + 12] 一样快。
但是 lea eax, [rbp + rcx*4] 只能在机器代码中编码为 lea eax, [rbp + rcx*4 + 0] (因为 addressing mode escape-code stuff ),这是一个 3 组件 LEA,因此在 Intel 上较慢(Sandybridge 系列上的 3 个周期延迟而不是 1 个周期,请参阅 https://agner.org/optimize/ 指令表和 microarch PDF )。在 AMD 上,即使使用 lea eax, [rdx + rcx*4],拥有缩放索引也会使其成为慢速 LEA
在 LEA 之外,在任何寻址模式中使用 RBP/R13 作为基础总是需要 disp8/32 字节或双字,但我认为实际 AGU 对于 3 分量寻址模式并不慢。所以这只是代码大小的影响。

其他情况包括 Which Intel microarchitecture introduced the ADC reg,0 single-uop special case?,其中 adc al, imm8 的短格式 2 字节编码为 2 uop,即使在 Skylake 等现代 uarch 上也是如此,其中 adc bl, imm8 为 1 uop。
因此,不仅 adc reg,0 特例不适用于通过 Haswell 在 Sandybridge 上的 adc al,0,Broadwell 和更新的忘记(或选择不)优化该编码解码为 uops 的方式。 (当然,您可以使用 3 字节 Mod/RM 编码对 adc al,0 进行手动编码,但汇编程序将始终选择最短的编码,因此 adc al,0 默认情况下将汇编为短格式。)只有字节寄存器有问题; adc eax,0 将使用 opcode ModRM imm8 3 字节编码,而不是 5 字节 opcode imm32
对于 op al,imm8 的其他情况,唯一的区别是代码大小,这只是间接影响性能。 (由于解码、uop-cache 打包和 I-cache 未命中)。
有关代码大小特殊情况的更多信息,请参阅 Tips for golfing in x86/x64 machine code,例如 xchg eax, ecx 为 1 字节,而 xchg edx, ecx 为 2 字节。

如果自上次 push/pop/call/ret 以来没有明确使用 RSP 或 ESP(当然沿着执行路径,而不是在静态代码布局中),add rsp, 8 可能需要额外的堆栈同步 uop。 ( What is the stack engine in the Sandybridge microarchitecture? )。这就是为什么像 clang 这样的编译器使用虚拟插入或弹出来保留/释放单个堆栈槽的原因:Why does this function push RAX to the stack as the first operation?

关于performance - 某些通用寄存器是否比其他寄存器更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62922332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com