gcc编译器优化项和链接操作的具体工作

来源:互联网 发布:概率编程与贝叶斯推断 编辑:程序博客网 时间:2024/05/22 15:30

-O0

这里只介绍优化编译的参数
-O用来开启优化编译选项。
-O0:默认模式,不做任何优化。

-O1

-O1:优化。该模式下对于一个大的函数或功能会花费更多的时间和内存。
在-O1下:编译会尝试减少代码体积和代码运行时间。但是并不执行会花费大量时间的优化操作。
在该模式下将打开一下优化选项:

优化选项 描述
-fdefer-pop 推迟推出函数调用的参数,对于那些需要在函数调用后必须取出(pop)函数参数的机器而言,打开该项编译器将把函数调用的参数压入栈,等必要时几个函数调用参数一起取出(pop)。这将节省处理时间。

-fdelayed-branch 如果对目标机支持这个功能,它试图重新排列指令,以便利用延迟分支(delayed branch)指令后面的指令空隙.

-fguess-branch-probability 使用启发式算法预测分之指令,增加指令的命中率,提升运行效果。

-fcprop-registers 使用寄存器之间copy-propagation传值,因为在函数中把寄存器分配给变量, 所以编译器执行第二次检查以便减少调度依赖性(两个段要求使用相同的寄存器)并且删除不必要的寄存器复制操作

-floop-optimize 通过优化如何生成汇编语言中的循环, 编译器可以在很大程序上提高应用程序的性能。 通常, 程序由很多大型且复杂的循环构成。 通过删除在循环内没有改变值的变量赋值操作, 可以减少循环内执行指令的数量, 在很大程度上提高性能。 此外优化那些确定何时离开循环的条件分支, 以便减少分支的影响

-fif-conversion if-then语句应该是应用程序中仅次于循环的最消耗时间的部分,简单的if-then语句可能在最终的汇编语言代码中产生众多的条件分支通过减少或者删除条件分支, 以及使用条件传送 设置标志和使用运算技巧来替换他们, 编译器可以减少if-then语句中花费的时间量。

-fif-conversion2 这种技术结合更加高级的数学特性, 减少实现if-then语句所需的条件分支。

-ftree-ccp

-ftree-dce

-ftree-dominator-opts

-ftree-dse

-ftree-ter

-ftree-lrs

-ftree-sra

-ftree-copyrename

-ftree-fre

-ftree-ch

-funit-at-a-time

-fmerge-constants

该模式下在不影响调试的状况下还会打开‘-fomit-frame-pointer优化项。
同时该模式不会为Ada编译器打开‘-ftree-sra’优化项,如需要则请使用命令参数输入‘-ftree-sra’进行优化。

-O2

进一步优化.GCC执行几乎所有支持的操作但不包括空间和速度之间权衡的优化。
-O2优化等级下,并不执行循环展开和函数“内联”优化操作。
与-O1比较该优化-O2将会花费更多的编译时间当然也会生成性能更好的代码。

-O2除了打开-O1的所有优化参数外还打开以下优化选项。

优化选项 描述
-fthread-jumps

-fcrossjumping

-foptimize-sibling-calls

-fcse-follow-jumps -fcse-skip-blocks

-fgcse -fgcse-lm

-fexpensive-optimizations

-fstrength-reduce

-frerun-cse-after-loop -frerun-loop-o

-fcaller-saves

-fpeephole2

-fschedule-insns -fschedule-insns2

-fsched-interblock -fsched-spec

-fregmove

-fstrict-aliasing

-fdelete-null-pointer-checks

-freorder-blocks -freorder-functions

-falign-functions -falign-jumps

-falign-loops -falign-labels

-ftree-vrp

-ftree-pre

还要注意-fgcse下关于请求-O2优化等级的用于计算goto的程序。

-O3

-O3:更进一步优化。-O3打开-O2指定的所有优化操作并且打开:

-finline-functions

-funswitch-loops

-fgcse-after-reload

优化项-O3

-Os:针对程序空间大小优化(多用于嵌入式系统)。
-Os使能-O2中除去会增加程序空间的所有优化参数。同时-Os还会执行更加优化程序空间的选项。
-Os会关闭以下优化选项:

优化选项 描述
-falign-functions

-falign-jumps

-falign-loops

-falign-labels

-freorder-blocks

-freorder-blocks-and-partition

-fprefetch-loop-arrays

-ftree-vect-loop-version

关于GCC编译的优化选项一共有-O0(默认),-O1,-O2,-O3及-Os五个参数。


第四步:链接 - - 目标二进制文件 -> 可执行二进制文件

gcc会调用ld进行链接,详细命令较复杂,不再陈述,了解进程即可

目标代码不能直接执行,要想将目标代码变成可执行程序,还需要进行链接操作。才会生成真正可以执行的可执行程序。
链接操作最重要的步骤就是将函数库中相应的代码组合到目标文件中。
将目标代码与各库函数进行链接并重定位,生成可执行程序。

库:是一组预先编译好的函数集合。

说明:标准库文件一般存储在/lib和/usr/lib目录中。
所有的库名都以lib开头。例如:libc.so(标准C语言函数库)、libm.so(数学运算函数库)
以.a结尾的是静态库;以.so结尾的库是动态库。
使用ar工具将目标文件收集起来,放到一个归档文件中。

说明:链接过程通常的形式如下:
gcc -o file file.o -L dirname -lxxx
-L:指定了链接时用到的库文件所在的目录。
-lxxx:指示链接的库函数名为libxxx.a

例子:编译产生可执行文件hello,搜索数学库以解决问题。
gcc -o hello hello.c /usr/lib/libm.a
或者
gcc -o hello hello.c -lm

例子:创建一个小型库
包含两个函数pro1、pro2,然后在示例程序中调用其中一个函数。

#includevoid pro1(int arg){printf("hello:%d\n", arg);}#includevoid pro2(char *arg){printf("welcome to:%s", arg);}void pro1(int);void pro2(char *);#include "lib.h"int main(){pro2("Linux world.");exit(0);}
0 0
原创粉丝点击