究竟如何做的gcc的优化? [英] How exactly does gcc do optimizations?

查看:89
本文介绍了究竟如何做的gcc的优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了了解GCC究竟做了优化,我已经写了两个程序与-O2编译,但组装code,还有一些分歧。在我的计划,我想在环路输出你好,并添加每个输出之间有一些延迟。这两个方案仅用于说明我的问题,我知道我可以用易挥发或汇编程序1达到我的目的。

In order to know how exactly the gcc do the optimization, I have written two program compiling with -O2, but there is some difference of the assembly code. In my programs, I want to output "hello" in the loop, and add some delay between each output. These two programs are only for illustrating my question, and I know I can using volatile or asm in program 1 to achieve my purpose.

程序1

#include <stdio.h>

int main(int argc, char **argv)
{
    unsigned long i = 0;
    while (1) {
        if (++i > 0x1fffffffUL) {
            printf("hello\n");
            i = 0;
        }
    }
}

与-O2编译,装配code是:

Compile with -O2, the assembly code is:

Disassembly of section .text.startup:

00000000 <_main>:
#include <stdio.h>

int main(int argc, char **argv)
{
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 10                sub    $0x10,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
   e:   66 90                   xchg   %ax,%ax
  10:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  17:   e8 00 00 00 00          call   1c <_main+0x1c>
  1c:   eb f2                   jmp    10 <_main+0x10>
  1e:   90                      nop
  1f:   90                      nop

程序2

int main(int argc, char **argv)
{
    unsigned long i = 0;
    while (1) {
        if (i > 0x1fffffffUL) {
            printf("hello\n");
            i = 0;
        }
        i++;
    }
}

与-O2编译,装配code是:

Compile with -O2, the assembly code is:

Disassembly of section .text.startup:

00000000 <_main>:
#include <stdio.h>

int main(int argc, char **argv)
{
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 10                sub    $0x10,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
   e:   31 c0                   xor    %eax,%eax
  10:   83 c0 01                add    $0x1,%eax
  13:   3d ff ff ff 1f          cmp    $0x1fffffff,%eax
  18:   76 f6                   jbe    10 <_main+0x10>
  1a:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
    while (1) {
        if (i > 0x1fffffffUL) {
            printf("hello\n");
            i = 0;
        }
        i++;
  21:   e8 00 00 00 00          call   26 <_main+0x26>

int main(int argc, char **argv)
{
    unsigned long i = 0;
    while (1) {
        if (i > 0x1fffffffUL) {
  26:   31 c0                   xor    %eax,%eax
  28:   eb e6                   jmp    10 <_main+0x10>
            printf("hello\n");
  2a:   90                      nop
  2b:   90                      nop
  2c:   90                      nop
  2d:   90                      nop
  2e:   90                      nop
  2f:   90                      nop

在方案1,的提高I 进行了优化,但是它不是在节目2.为什么出现这种情况?什么样的规则与-O2优化这两种方案在使用是gcc?

In program 1, the increase of i is optimized out, but it's not in program 2. Why this happens? What rules is gcc using when optimizing with -O2 for these two programs?

推荐答案

问为什么关于优化通常是浪费时间,因为那里的的没有规则,其中优化经营 - 除好像:优化器可能不会改变符合code的观察行为

Asking "why" about optimizers is usually a waste of time, because there are no "rules" by which optimizers operate -- other than "as if": The optimizer may not change the observable behaviour of conforming code.

你的两种方案的看得见的行为是打印你好反反复复。

The "observable behaviour" of both your programs is to print "hello" repeatedly.

在你的第一个程序,计数被优化掉,使得观察到的行为发生得更快。的这是一个优化的工作。的竭诚为您code现在更有效率!

In your first program, the counting is optimized away, making the observable behaviour happen faster. That is the job of an optimizer. Be happy your code is more efficient now!

在你的第二个方案,点票的的优化掉,因为不知何故优化 - 在这个版本这个编译< STRONG>这个设置 - 没有看到,它可能离不开它。为什么?谁知道(比编译器的优化器模块的维护等)?

In your second program, the counting is not optimized away, because somehow the optimizer -- in this version of this compiler with this setting -- did not see that it could do without it. Why? Who knows (other than the maintainer of the compiler's optimizer module)?

如果您的所需的的行为是有输出之间的延迟,使用类似的 thrd_sleep()。空循环计数分别推迟对C64 BASIC 2.0程序的方式,但他们不应该在C中使用,确切的原因,你只需观察:你永远不知道优化做什么

If your desired behaviour is to have a delay between outputs, use something like thrd_sleep(). Empty count loops were a way to delay BASIC 2.0 programs on the C64, but they should not be used in C, for the exact reason you just observed: You never know what the optimizer does.

这篇关于究竟如何做的gcc的优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆