编译期的优化

来源:互联网 发布:学算法入门看什么书 编辑:程序博客网 时间:2024/05/16 05:16

    gcc 是可以对代码进行一定优化的编译器,有一系列options可以用来优化使得代码运行地更快以及生成的可执行文件更小。当然,优化是一个很复杂的过程,源码中的每一句或者每一块儿代码都可以对应许多组合形式的机器码,而优化的过程就是尽量找到比较好的机器码组合使得执行效率更好,总体说来,gcc对代码的优化主要分为两个层次,一个是source level级,一个是speed -space tradeoff级,以下详细说明之

  • source -level
    这一级的优化又可以分为两种,common sudexpression elimination 和 function inlining,以代码示例
    //subexpression elemination,如下代码x = cos(v) *(1 + sin(u))  +  sin(w)*(1-sin(u/2));//gcc 转换为下述代码t = sin(u/2);x = cos(v) *(1+t) + sin(w)*(1-t);

    这里的中间变量t只是为了说明意思,并不是真正用t,这种优化很有效果,既能加快速度,又能减少代码体积
    函数的反复调用是占了很大比重的时间开销,因此把一些简单的函数内联就能降低一些时间开销如下:
    duoble sq(double x){return x*x;}for (int i = 0; i < 100000; ++i){sum += sq(i+0.5); }
    编译器将代码转换为下面,
    for (int i = 0; i < 100000; ++i){double t = i + 0.5;sum += t*t;}


  • speed-space tradeoff
    编译器在这一级的优化不能再减小程序体积的情况下加快速度,必须在两者之间进行取舍。如将循环展开,
    for (int i = 0; i < 4; ++i){y[i] = i;}y[0] = 0;y[1] = 1;y[2] = 2;y[3] = 3;

    当然在循环次数不大的时候,这样优化看不出有神马明显改善,但将循环展开的好处是可以进行并行计算。



    optimization levels
    gcc 将代码的优化分为0-3四个层次,-Olevel  level取值为0-3
    -O0或者没有使用这个option(默认),此时gcc对代码不做任何形式的转化,这在dubug的时候比较好
    -O1或者-O这个级别的优化没有进行speed-space trade off的代码优化,相对应与-O0,这时候可执行文件的体积更小,速度更快
    -O2 在-O1的基础上进行进一步的优化,包括instruction scheduling ,这一级的优化不会增加体积,但会加快速度,
    -O3 在-O2的基础上进行expensive优化,在加快速度的同时也增加了程序体积
    -funroll-loops 跟其他option独立,展开虚幻,优化结果的好坏的看情况
    -Os 这个优化选取能使可执行文件体积减小的优化方式,(当然体积更小有时候程序执行速度也会更快)

原创粉丝点击