assembly - 在内存位置调用 `add` 是否比在寄存器上调用它然后移动值更快?

标签 assembly x86 x86-64 micro-optimization

什么更快:

add DWORD PTR [rbp-0x4],1

 mov    eax,DWORD PTR [rbp-0x4]
 add    eax,1
 mov    DWORD PTR [rbp-0x4],eax

我已经看到编译器生成的第二个代码,所以也许在寄存器上调用 add 会快得多?

最佳答案

它们都解码为相同数量的后端微指令,但内存目标 add 在现代 Intel/AMD CPU 上以更少的融合域微指令通过前端获取这些微指令。

在 Intel CPU 上,add [mem], imm 解码为微融合加载+添加和微融合存储地址+存储数据,因此总共 2 个融合域微指令前端。 AMD CPU 始终将内存操作数与 ALU 操作分组在一起,而不将其称为“微融合”,这就是它们一直以来的工作方式。 ( https://agner.org/optimize/INC instruction vs ADD 1: Does it matter? )。

<小时/>

第一种方法不会将值保留在寄存器中,因此如果表达式的值是,则无法将其用作++a的一部分用过的。仅针对对内存的副作用。

<小时/>

使用 [rbp - 4] 并增加内存中的本地值,这听起来像是未优化/ Debug模式的代码,您不应该查看这些代码优化的代码通常使用[rsp +-constant]来寻址局部变量,并且(除非变量是 volatile )不会只是存储它立即又回到内存中。

Why does clang produce inefficient asm with -O0 (for this simple floating point sum)? - 在 Debug模式下编译,又名-O0(默认)单独编译每个C语句,并将每个变量视为 volatile ,这是完全可怕的。

参见How to remove "noise" from GCC/clang assembly output?了解如何让编译器生成有趣的 asm。编写一个接受参数并返回值的函数,这样它就可以在不优化或将常量传播到 mov eax,constant_result 的情况下执行某些操作>.

关于assembly - 在内存位置调用 `add` 是否比在寄存器上调用它然后移动值更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61377311/

相关文章:

c++ - 在裸函数中插入 Asm

assembly - 这些线在 assembly 中起什么作用?

assembly - MIPS - 从用户输入将整数存储在数组中

assembly - FMA(融合乘法加法)指令是否总是产生与mul然后add指令相同的结果?

assembly - 编码汇编代码行 "xorq, %rdx, %rdx"需要多少字节?

assembly - 是否可以反向解码 x86-64 指令?

assembly - x64 调用约定中前 4 个参数的影子空间的用途是什么

assembly - 如何强制 NASM 将 [1 + rax*2] 编码为 disp32 + index*2 而不是 disp8 + base + index?

c - x86内核中的键盘IRQ

assembly - Qemu 在设置 GDT 时无限重启