【问题标题】:gcc optimisation with LEA [duplicate]使用 LEA 进行 gcc 优化 [重复]
【发布时间】:2013-04-26 17:21:13
【问题描述】:

我正在摆弄 gcc 的优化选项,发现这些行:

int bla(int moo) {
  return moo * 384;
}

被翻译成这些:

0:   8d 04 7f                lea    (%rdi,%rdi,2),%eax
3:   c1 e0 07                shl    $0x7,%eax
6:   c3                      retq

我理解移位表示乘以 2^7。并且第一行必须是乘以 3。

所以我对“lea”行完全感到困惑。 lea 不应该加载地址吗?

【问题讨论】:

  • 为了完整性:地址操作数获取的语法是:±d(A,B,C) 将被翻译成 A±d + B * C
  • 顺便说一下,唯一使用 AGU 的现代 CPU 是 lea 是 Intel Atom。在所有其他现代 CPU 上,它都用于 ALU。然而它仍然很有用,因为它结合了几个操作,有一个任意的输出寄存器,并且不改变标志。另外,这种形式(64位地址,32位结果)是lea在64位模式下的最短编码。

标签: gcc assembly optimization


【解决方案1】:

lea (%ebx, %esi, 2), %edi 只是计算ebx + esi*2 并将结果存储在edi 中。

即使lea 被设计为计算和存储有效地址,它也可以并且经常被用作优化技巧来对某些不是内存地址。

lea    (%rdi,%rdi,2),%eax
shl    $0x7,%eax

相当于:

eax = rdi + rdi*2;
eax = eax * 128;

由于moordi 中,它会将moo*384 存储在eax

【讨论】:

  • 非常感谢!我知道你可以用 lea 做欺骗的东西而不改变标志等,但是这个......
【解决方案2】:

这是针对 x86 内核的标准优化技巧。 AGU(地址生成单元)是处理器中生成地址的子部分,能够进行简单的算术运算。它不是一个成熟的 ALU,但有足够的晶体管来计算索引和缩放地址。添加和转移。 LEA,加载有效地址指令是一种调用 AGU 中的逻辑并使其计算简单表达式的方法。

这里的优化机会是 AGU 独立于 ALU 运行。所以你可以获得超标量执行,两条指令同时执行。

这实际上并没有在您的代码 sn-p 中明显发生,但如果在需要 ALU 的所示指令之前进行了计算,则可能会发生这种情况。这是一个技巧,只有在更简单的 cpu 内核、486 和 Pentium 年份才能真正得到回报。现代处理器有多个 ALU,所以不再需要这个技巧了。

【讨论】:

  • 另请注意,班次通常比IMUL 快;并且用移位替换“乘以常数”也是许多 CPU 的常见优化。
  • 启用它的精确 GCC 优化标志是什么(例如 -fuse-lea-O3 暗示)。
猜你喜欢
  • 2020-12-18
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 2016-06-13
  • 1970-01-01
相关资源
最近更新 更多