GCC优化级别。哪个更好?

时间:2015-10-05 03:27:56

标签: gcc optimization compilation performance-testing compiler-optimization

我专注于GCC编译程序的CPU /内存消耗。

执行使用O3编译的代码在资源方面总是如此贪婪吗?

是否有任何科学参考或规范显示不同级别的Mem / cpu消耗的差异?

处理此问题的人通常关注这些优化对执行时间,编译代码大小和能量的影响。但是,我找不到太多关于资源消耗的工作(通过启用优化)。

提前致谢。

1 个答案:

答案 0 :(得分:11)

不,没有绝对的方法,因为optimization in compilers是一门艺术(甚至没有明确定义,可能是undecidableintractable)。

但首先是一些指导原则:

  • 确保您的程序正确 并且在优化任何内容之前没有错误,所以请调试并测试您的程序

  • 有精心设计的测试用例和代表性基准(见this)。

  • 请确保您的程序没有undefined behavior (这很棘手,请参阅this),因为GCC会奇怪地进行优化(但是根据C99或C11标准,如果您的代码中有UB,则通常是正确的;在调试阶段使用-fsanitize=style选项(以及gdbvalgrind ....)。

  • profile您的代码(在各种基准测试中),特别是要找出哪些部分值得进行优化工作;通常(但并非总是)大部分CPU时间都发生在一小部分代码中(经验法则:在20%的代码中花费80%的时间;在gcc编译器等某些应用程序上,这不是真的,检查gcc -ftime-report以询问gcc以显示在各种编译器模块中花费的时间)....大部分时间"premature optimization is the root of all evil"(但这种格言有例外)。

  • 改进您的源代码(例如,仔细正确地使用 restrictconst,添加一些pragmasfunction或{ {3}}属性,也许明智地使用一些GCC variable __builtin_expect__builtin_prefetch - 来自builtins - ,__builtin_unreachable ...)

    < / LI>
  • 使用最近的编译器。 this的当前版本(2015年10月)是GCC(以及2018年6月的5.2)并且在优化方面取得了持续进展;您可以考虑从源代码编译GCC以获得最新版本。

  • 在编译器中启用所有警告gcc -Wall -Wextra),并尽力避免所有警告;只有在您要求优化时才会出现一些警告(例如,使用-O2

  • 通常情况下,使用-O2 -march=native(或者-mtune=native进行编译,如果您确实添加了良好的-march选项,我认为您不是GCC 8。 。)并使用

  • 对您的程序进行基准测试
  • 通过编译并链接-flto以及相同的优化标记来考虑cross-compiling。例如,将CC= gcc -flto -O2 -march=native放入Makefile(然后从-O2 -mtune=native移除CFLAGS)...

  • 通常也尝试使用-O3 -march=native(但并非总是如此,有时使用-O2的代码比使用-O3略快一些,但这种情况并不常见)你可能会得到一个小小的代码改进超过-O2

  • 如果您想优化生成的程序大小,请使用-Os代替-O2-O3;更一般地说,不要忘记阅读文档的link-time optimization部分。我想-O2-Os都会优化堆栈使用(这与内存消耗非常相关)。并且一些GCC优化能够避免malloc(这与堆内存消耗有关)。

  • 您可以考虑Options That Control Optimization-fprofile-generate-fprofile-use-fauto-profile profile-guided optimizations

  • 深入了解options的文档,它有很多GCC&amp; optimization个参数(例如-ffast-math-Ofast ...)和code generation,您可能需要花费数月时间尝试更多的参数;请注意,其中一些并非严格符合C标准!

  • 最近parametersGCC可以发出Clang调试信息(不知何故&#34;近似&#34;如果已经应用了强大的优化),即使在优化时也是如此-O2-g都值得(在优化的可执行文件中,您仍然可以DWARF继续使用)

  • 如果您有大量时间花费(数周或数月),您可以使用use the gdb debugger(或其他一些插件)自定义GCC,以添加您自己的新(特定于应用程序)优化过程;但这很困难(你需要了解GCC的内部陈述和组织)并且可能很少值得,除非在非常具体的情况下(那些你可以证明花费数月的时间来改进优化的理由)

  • 您可能想了解程序的堆栈使用情况,因此请使用MELT

  • 您可能希望了解发出的汇编程序代码,除了优化标志之外还使用-S -fverbose-asm(并查看生成的.s汇编程序文件)

  • 您可能想了解GCC的内部工作,使用各种-fstack-usage标记(您将获得数百个转储文件!)。

当然上面的待办事项列表应该以迭代和敏捷的方式使用。

对于-fdump-*个错误,请考虑memory leaks和多个-fsanitize= valgrind。另请阅读debugging options(以及garbage collection),特别是GC handbook,以及有关编译时垃圾收集技术的内容。

了解GCC中的Boehm's conservative garbage collector

还要考虑MILEPOST projectOpenMPOpenCLMPI等等......请注意multi-threading是一项困难的艺术。

请注意,即使GCC开发人员也经常无法预测此类优化的影响(生成的二进制文件的CPU时间)。不知何故,优化是一种黑色艺术。

也许gcc-help@gcc.gnu.org可能是一个提出更具体的问题的好地方。关于parallelization

中的优化的精确且有针对性的问题

您也可以basile starynkevitchnet更专注问题联系我{(并提及原始问题的网址) )

对于有关优化的科学论文,您会发现很多。从GCCACM TOPLAS等开始...搜索迭代编译器优化等....并更好地定义要优化的资源(内存消耗意味着旁边没什么....)。