为了账号安全,请及时绑定邮箱和手机立即绑定

停用GCC中的所有优化选项

停用GCC中的所有优化选项

侃侃无极 2019-10-21 15:43:50
使用GCC编译C程序的默认优化级别是-O0。这会根据GCC文档关闭所有优化。例如:    gcc -O0 test.c 但是,要检查-O0是否真的关闭了所有优化。我执行了以下命令:    gcc -Q -O0 --help=optimizers 在这里,我有点惊讶。我启用了大约50个选项。然后,我使用以下命令检查了传递给gcc的默认参数:    gcc -v 我懂了:Using built-in specs.COLLECT_GCC=gccCOLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapperTarget: x86_64-linux-gnuConfigured 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-gnuThread model: posixgcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 所以我的结论是,-O0我提供给程序的标志没有被其他东西覆盖。实际上,我正在寻求从头开始实现一种工具,该工具可以生成优化选项的随机序列,并将生成的序列与默认级别0-3进行比较。就像“ acovea”一样。因此,我想将生成的序列与零优化级别(应该是-O0)进行比较您能解释一下为什么默认情况下启用了50个选项-O0吗?我想到的一个想法是使用50次编译-O0并关闭默认优化。你怎么看?-O0-fno-OPTIMIZATION_NAME
查看完整描述

3 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

Stricto sensu,GCC编译器的中端由优化遍历的序列(实际上是嵌套树,在编译过程中会动态更改)组成,因此,如果GCC没有进行优化,则将无法发出任何代码。


想想另一种方式:输入语言GCC是相当丰富的(即使是纯C,在那里你有while,for,...),但中间GIMPLE语言是更差(特别是GIMPLE / SSA),所以你需要到应用一些转换以将源AST转换为Gimple。这些转换是优化过程,几乎可以定义为。


另请参阅该答案和该答案的图片(SVG图片),并阅读此处提到的参考资料。


您应该理解-O0为禁用生成某些可执行文件不需要的任何其他优化(例如,-O1etc等提供的优化)。


查看完整回答
反对 回复 2019-10-21
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

为了回答我的问题,我做出了一些结论和假设:


因此,我想说用O0进行编译并不意味着不会应用任何优化。如上面@abligh所述,可以减少编译时间并改善调试效果的选项将打开。


换句话说,O0在编译级别上正在优化。生成的二进制文件未经过优化,以简化调试过程。


我举一个例子:该选项在O0级别启用


渐进式循环优化


在GCC文档中:


此选项告诉循环优化器使用语言约束来得出循环迭代次数的界限。这假定循环代码不会通过例如引起有符号整数溢出或超出范围的数组访问来调用未定义的行为。循环迭代次数的界限用于指导循环展开和剥离以及循环退出测试优化。默认情况下启用此选项。


因此,对于GCC 4.8.x,默认情况下将启用近50个选项。


查看完整回答
反对 回复 2019-10-21
  • 3 回答
  • 0 关注
  • 1272 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信