【问题标题】:Explanation of gcc optimizationgcc优化说明
【发布时间】:2013-02-19 09:09:48
【问题描述】:

出于黑客的好奇心,我想知道gcc如何巧妙地优化下面的功能?

int c() {
        int i, j = 0;
        for (i = 0; i < 10; i++) {
                j += i;
        }
        return j;
}

$objdump -D c.o 下面是 arm 但 x86 在逻辑上没有什么不同。

00000000 <c>:
   0:   202d        movs    r0, #45 ; 0x2d
   2:   4770        bx  lr

我最想知道这是一系列优化的结果还是模板匹配之类的结果?有没有关于这种优化的文档?

【问题讨论】:

  • 用 c 重新注册会吸引更多人...

标签: c performance optimization gcc


【解决方案1】:

优化器分阶段/通过...当您指定 -O2 时,会启用许多优化。这里发挥作用的主要优化是

  1. loop unrolling
  2. constant propagation
  3. constant folding
  4. dead-code elimination

http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

所以这段代码

int i, j = 0;
for (i = 0; i < 10; i++) {
    j += i;
}
return j;

循环展开后变为

int i, j = 0;
i=0; j += i;
i=1; j += i;
i=2; j += i;
i=3; j += i;
i=4; j += i;
i=5; j += i;
i=6; j += i;
i=7; j += i;
i=8; j += i;
i=9; j += i;
return j;

在不断传播之后

int i, j = 0;
i=0; j += 0;
i=1; j += 1;
i=2; j += 2;
i=3; j += 3;
i=4; j += 4;
i=5; j += 5;
i=6; j += 6;
i=7; j += 7;
i=8; j += 8;
i=9; j += 9;
return j;

消除死代码后

j = 0;
j += 0;
j += 1;
j += 2;
j += 3;
j += 4;
j += 5;
j += 6;
j += 7;
j += 8;
j += 9;
return j;

constant folding之后

j = 45;
return j;

最后,

return 45;

【讨论】:

  • 很抱歉对旧答案投了反对票,但这并不是对 GCC 执行的转换的准确描述(尽管它确实有效,并且是各种编译器优化的合理近似和简洁演示)。如果您想查看 GCC 内部对此测试用例的工作情况,您可以通过 -fdump-tree-cunroll-all 并读取输出。我的主要反对意见是这些分析中的大多数都是相互交织的,GCC 只决定展开,因为它知道它可以折叠归纳变量,而 cunroll 进行折叠/传播,因此永远不会有任何死代码需要消除。
猜你喜欢
  • 2015-07-09
  • 1970-01-01
  • 2013-03-05
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 2021-12-08
  • 2022-01-15
  • 2020-05-13
相关资源
最近更新 更多