【问题标题】:Is the gcc insane optimisation level (-O3) not insane enough?gcc 疯狂的优化级别 (-O3) 还不够疯狂吗?
【发布时间】:2011-02-23 02:01:47
【问题描述】:

作为回答另一个问题的一部分,我想表明gcc (-O3) 的疯狂优化水平基本上会去除 main.xml 中未使用的所有变量。代码是:

#include <stdio.h>
int main (void) {
   char bing[71];
   int x = 7;
   bing[0] = 11;
   return 0;
}

gcc -O3 的输出是:

    .file "qq.c"
    .text
    .p2align 4,,15
.globl main
    .type main, @function
main:
    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret
    .size main, .-main
    .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section .note.GNU-stack,"",@progbits

现在我可以看到它已删除局部变量,但其中仍有相当多的浪费。在我看来,整个:

    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret

部分可以替换为更简单的:

    xorl %eax, %eax
    ret

有人知道为什么gcc 不执行此优化吗?我知道这对于main 本身来说会节省很少的钱,但是,如果这也是使用普通函数完成的,那么在大规模循环中不必要地调整堆栈指针的效果会相当大。

用于生成程序集的命令是:

gcc -O3 -std=c99 -S qq.c

【问题讨论】:

  • 能否包含调用 gcc 的完整命令?

标签: optimization gcc stack-frame


【解决方案1】:

您可以使用-fomit-frame-pointer 编译器标志启用该特定优化。这样做会使某些机器上的调试变得不可能,并且在其他所有机器上都变得更加困难,这就是它通常被禁用的原因。

虽然您的 GCC 文档可能会说 -fomit-frame-pointer 在不同的优化级别启用,但您可能会发现情况并非如此——您几乎肯定必须自己显式启用它。

【讨论】:

    【解决方案2】:

    打开-fomit-frame-pointer (source) 应该可以摆脱额外的堆栈操作。

    GCC 显然将它们保留在其中,因为它们有助于调试(在需要时获取堆栈跟踪),尽管文档指出 -fomit-frame-pointer 是从 GCC 4.6 开始的默认值。

    【讨论】:

      猜你喜欢
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-17
      • 2021-01-21
      • 2011-01-06
      • 2011-01-27
      相关资源
      最近更新 更多