gcc优化

一、空间优化(减少可执行文件的大小)

主要有两个方向:1)去除符号信息 2)只链接有用的东西

示例引自http://wiki.wxwidgets.org/Reducing_Executable_Size:
Test #1
# wxGTK compiled with:
#   ./configure --disable-debug --disable-shared
#   make
$ ls -l minimal
-rwxr-xr-x 1 frm frm 4,3M 2009-02-11 17:04 minimal*
$ size minimal
   text    data     bss     dec     hex filename
3698330   10436   49692 3758458  39597a minimal
$ strip --strip-all minimal
$ ls -l minimal
-rwxr-xr-x 1 frm frm 3,6M 2009-02-11 17:23 minimal*
$ strip --remove-section=.comment --remove-section=.note minimal
$ ls -l minimal
-rwxr-xr-x 1 frm frm 3,6M 2009-02-11 17:28 minimal*
I.e. using --strip-all provided a 17% improvement. Removing the .comment and .note sections didn't produce any noticeable enhancement.
Test #2
Now, let's test the -ffunctions-sections & co options:
# wxGTK compiled with:
#   export CXXFLAGS="-ffunction-sections -fdata-sections"
#   export LDFLAGS="-Wl,--gc-sections"
#   ./configure --disable-debug --disable-shared
#   make
$ ls -l minimal
-rwxr-xr-x 1 frm frm 3,1M 2009-02-11 17:34 minimal*
$ strip --strip-all minimal
$ ls -l minimal
-rwxr-xr-x 1 frm frm 2,6M 2009-02-11 17:36 minimal*
As you can see, using the -ffunctions-sections option when compiling and the -Wl,--gc-sections option when linking produces great results. The final executable (after stripping) is 30% smaller than the one obtained in test #1!
Test #3
Now, let's test the -Os option (together with the -ffunction-sections option):
# wxGTK compiled with:
#   export CXXFLAGS="-ffunction-sections -fdata-sections -Os"
#   export LDFLAGS="-Wl,--gc-sections"
#   ./configure --disable-debug --disable-shared
#   make
$ ls -l minimal
-rwxr-xr-x 1 frm frm 2,5M 2009-02-11 18:35 minimal*
$ strip --strip-all minimal
$ ls -l minimal
-rwxr-xr-x 1 frm frm 1,8M 2009-02-11 18:35 minimal*
The final executable (after stripping) is 50% smaller than the one obtained in test #1!

结论
1)你可以通过在可执行文件上进行strip --strip-all,大概有%20-%30的改善
2)如果可能,你可以在编译静态库时添加-ffunction-sections -fdata-sections -Os选项,在链接时 -Wl,--gc-sections,获得大约%30-%50的改善


strip的目的是在可执行文件中去除不必要的符号信息(副作用是,生成的程序调试困难)
-ffunction-sections -fdata-sections 加上  -Wl,--gc-sections目的是仅链接需要的接口或者变量。


二、性能优化 


gcc的性能优化是分为5个级别的: -O(O0) -O1 -O2 -Os -O3,各个级别都是一组优化选项的组合

gcc优化_第1张图片

每个级别都有不同的目标:
1)-O(O0) 默认选项,也可显式声明 不做任何优化
2)-O1    尽量不增加编译时间的前提下,生成优化后的程序。在编译时间和优化之间进行了折中。
3)-O2    涵盖-O1的优化选项,在空间和时间之间进行了折中,尽量在少增加空间的前提下,进行了优化(loop unrolling and function inlining 都没有涵盖)
4)-Os    与O2类似,但更强调空间,去掉了-O2中有关对齐的选项,节省空间
5)-O3    与空间相比,更强调性能,在-O2的基础上增加了部分优化  但效果一般,使用较少(可能空间过大,引起cache命中率下降,导致性能下降)

总体来说,若无法确定自己的需求O2是比较靠谱的选择


优化选项主要有如下几类
对齐、inline 、march、momit-leaf-frame-pointer、-funroll-loops、分支预测等。
简单介绍下loop unrolling


示例1:
for (int i=0; i<n; i++)
{
  sum += data[i];
}
示例2:
for (int i=0; i<n; i+=4)
{
  sum1 += data[i+0];
  sum2 += data[i+1];
  sum3 += data[i+2];
  sum4 += data[i+3];
}
sum = sum1 + sum2 + sum3 + sum4;
could run faster. If you get a cache miss or other stall in one calculation there are still three other dependency chains that don't depend on the stall. A out of order CPU can execute these.
一个循环体中的指令数往往较少,若他们之间没有明显的依赖关系。可能会优化成示例2的形式。在乱序执行的cpu中,若某条指令未准备好,可执行其他指令,而不是进行等待。
引文:http://www.linuxjournal.com/article/7269

你可能感兴趣的:(性能优化,文件大小,O2,strip,优化选项)