c++ - 为什么编译器会生成这个程序集?

标签 c++ gcc assembly compiler-optimization

在单步执行一些 Qt 代码时,我遇到了以下问题。 QMainWindowLayout::invalidate()函数有如下实现:

void QMainWindowLayout::invalidate()
{
QLayout::invalidate()
minSize = szHint = QSize();
}

编译成这样:

<invalidate()>        push   %rbx
<invalidate()+1>      mov    %rdi,%rbx
<invalidate()+4>      callq  0x7ffff4fd9090 <QLayout::invalidate()>
<invalidate()+9>      movl   $0xffffffff,0x564(%rbx)
<invalidate()+19>     movl   $0xffffffff,0x568(%rbx)
<invalidate()+29>     mov    0x564(%rbx),%rax
<invalidate()+36>     mov    %rax,0x56c(%rbx)
<invalidate()+43>     pop    %rbx
<invalidate()+44>     retq

从invalidate+9 到invalidate+36 的程序集看起来很愚蠢。首先,代码将 -1 写入 %rbx+0x564 和 %rbx+0x568,然后将 -1 从 %rbx+0x564 加载回寄存器,只是为了将其写入 %rbx+0x56c。这似乎是编译器应该能够轻松地优化为立即的另一个 Action 。

那么这个愚蠢的代码(如果是的话,为什么编译器不优化它?)或者这是否比立即使用另一个 Action 更聪明和更快?

(注意:此代码来自 ubuntu 提供的正常发布库构建,因此它可能是由 GCC 在优化模式下编译的。minSizeszHint 变量是QSize 类型的普通变量。)

最佳答案

当你说它很愚蠢时,你不确定你是否正确。我认为编译器可能正在尝试优化这里的代码大小。没有 64 位立即到内存 mov 指令。所以编译器必须像上面那样生成 2 个 mov 指令。它们每个都是 10 个字节,生成的 2 个移动是 14 个字节。它已被写入,因此很可能没有内存延迟,因此我认为您不会在这里受到任何性能影响。

关于c++ - 为什么编译器会生成这个程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16679131/

相关文章:

c++ - 我可以仅针对 boost 单元测试失败获得日志输出吗

c++ - boost::rtree 受 gcc 编译器的影响很大

C++ eigen3 线性代数库,奇怪的性能结果

assembly - 内存和汇编语言/操作系统

c++ - 在方法中更改类的私有(private)值而不将更改返回给 main()

c++ - 为什么类可以定义在头文件中?

c++ - 当出现段错误时,更改显示的消息错误

c++ - 为什么使用 gcc 4.7 编译时会出现此堆栈跟踪,而使用较旧的 4.3 之前版本则不会出现?

c - 将编译代码与 NASM 和 MSVC 链接时 Unresolved reference

assembly - 两个寄存器中8位数字相加(8位也可以,16位不能用)