我专注于GCC编译程序的CPU /内存消耗。
执行使用O3编译的代码在资源方面总是如此贪婪吗?
是否有任何科学参考或规范显示不同级别的Mem / cpu消耗的差异?
处理此问题的人通常关注这些优化对执行时间,编译代码大小和能量的影响。但是,我找不到太多关于资源消耗的工作(通过启用优化)。
提前致谢。
答案 0 :(得分:11)
不,没有绝对的方法,因为optimization in compilers是一门艺术(甚至没有明确定义,可能是undecidable或intractable)。
但首先是一些指导原则:
确保您的程序正确 并且在优化任何内容之前没有错误,所以请调试并测试您的程序
有精心设计的测试用例和代表性基准(见this)。
请确保您的程序没有undefined behavior (这很棘手,请参阅this),因为GCC会奇怪地进行优化(但是根据C99或C11标准,如果您的代码中有UB,则通常是正确的;在调试阶段使用-fsanitize=
style选项(以及gdb
和valgrind ....)。
profile您的代码(在各种基准测试中),特别是要找出哪些部分值得进行优化工作;通常(但并非总是)大部分CPU时间都发生在一小部分代码中(经验法则:在20%的代码中花费80%的时间;在gcc
编译器等某些应用程序上,这不是真的,检查gcc -ftime-report
以询问gcc
以显示在各种编译器模块中花费的时间)....大部分时间"premature optimization is the root of all evil"(但这种格言有例外)。
改进您的源代码(例如,仔细正确地使用 restrict
和const
,添加一些pragmas或function或{ {3}}属性,也许明智地使用一些GCC variable __builtin_expect
,__builtin_prefetch
- 来自builtins - ,__builtin_unreachable
...)
使用最近的编译器。 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& optimization个参数(例如-ffast-math
,-Ofast
...)和code generation,您可能需要花费数月时间尝试更多的参数;请注意,其中一些并非严格符合C标准!
最近parameters和GCC可以发出Clang调试信息(不知何故"近似"如果已经应用了强大的优化),即使在优化时也是如此-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 project,OpenMP,OpenCL,MPI等等......请注意multi-threading是一项困难的艺术。
请注意,即使GCC开发人员也经常无法预测此类优化的影响(生成的二进制文件的CPU时间)。不知何故,优化是一种黑色艺术。
也许gcc-help@gcc.gnu.org
可能是一个提出更具体的问题的好地方。关于parallelization
您也可以basile
starynkevitch
点net
与更专注问题联系我{(并提及原始问题的网址) )
对于有关优化的科学论文,您会发现很多。从GCC,ACM TOPLAS等开始...搜索迭代编译器优化等....并更好地定义要优化的资源(内存消耗意味着旁边没什么....)。