sta*_*icx 14 c optimization gcc performance-testing compiler-optimization
使用GCC编译C程序的默认优化级别是-O0.根据GCC文档关闭所有优化.例如:
gcc -O0 test.c
Run Code Online (Sandbox Code Playgroud)
但是,要检查-O0是否真的关闭了所有优化.我执行了这个命令:
gcc -Q -O0 --help=optimizers
Run Code Online (Sandbox Code Playgroud)
在这里,我有点惊讶.我启用了大约50个选项.然后,我使用以下方法检查了传递给gcc的默认参数:
gcc -v
Run Code Online (Sandbox Code Playgroud)
我懂了:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-
2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --
enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --
program-suffix=-4.8 --enable-shared --enable-linker-build-id --
libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-
gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-
sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-
time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --
with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-
cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-
java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-
jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-
directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-
gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --
with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
Run Code Online (Sandbox Code Playgroud)
所以我的结论是,-O0
我提供给程序的旗帜没有被其他东西所覆盖.
实际上,我正在寻求从头开始实现一个生成随机优化选项序列的工具,并将生成的序列与默认级别0-3进行比较.就像"acovea".所以,我想将我生成的序列与零优化级别(应该是-O0
)进行比较
你能解释一下为什么默认启用50个选项-O0
吗?
我想到的一个想法是使用50次编译-O0
和关闭默认优化.你怎么看?-O0
-fno-OPTIMIZATION_NAME
好
gcc -O0 `gcc -Q -O0 --help=optimizers 2>&1 | perl -ane 'if ($F[1] =~/enabled/) {$F[0] =~ s/^\s*-f/-fno-/g;push @o,$F[0];}} END {print join(" ", @o)'` your args here
Run Code Online (Sandbox Code Playgroud)
将关闭所有选项(哎呀).
更严重的是,如果你是涵盖了所有优化状态,使优化参数(你需要做反正)的列表,并明确打开或关闭每一个与-fmyflag
或-fno-myflag
.这实质上回答了你的第二个问题.
但是,您可能会认为在关闭所有-O
级别的优化时不值得.
至于为什么会这样,那就是"太宽泛"(即你不得不问问谁写的)和'因为那是什么https://github.com/gcc-mirror/gcc/blob/master/gcc/ toplev.c做'.
请注意,文档没有说-O0
禁用优化.它说(来自手册页):
-O0
减少编译时间并使调试产生预期的结果.这是默认值.
通过暗示可能存在优化,不增加编译时间并且不影响调试,并且这些将保持开启.
为了回答我的问题,我做了一些结论和假设:
所以我要说的是,使用 O0 编译并不意味着不会应用任何优化。正如 @abligh 上面所说,将打开减少编译时间并更好地进行调试的选项。
也就是说,O0是在编译层面进行优化。为了简化调试过程,生成的二进制文件未进行优化。
我举个例子:这个选项在O0级别启用
-faggressive-loop-优化
在海湾合作委员会文档中:
此选项告诉循环优化器使用语言约束来导出循环迭代次数的界限。这假设循环代码不会通过例如导致有符号整数溢出或越界数组访问来调用未定义的行为。循环迭代次数的界限用于指导循环展开和剥离以及循环退出测试优化。默认情况下启用此选项。
因此对于 GCC 4.8.x,默认打开了近 50 个选项。