将代码编译为单个自动合并文件,以允许编译器更好地进行代码优化

shu*_*alo 3 c c++ optimization compilation

假设您有一个使用C,C++或任何其他使用"compile-objects-then-link-them"-scheme的语言的程序.

当你的程序不小时,它可能会破坏几个文件,以便简化代码管理(并缩短编译时间).此外,在一定程度的抽象之后,您可能具有深度调用层次结构.特别是在最低级别,任务最重复,最常见的是你想强加一个通用的框架.

但是,如果将代码分段为不同的目标文件并对代码使用非常抽象的体系结构,则可能会造成性能(如果您或您的主管强调性能,这会很糟糕).

循环这种方法的一种方法可能是广泛的内联 - 这是模板元编程的方法:在每个翻译单元中,您包括一般,灵活结构的所有代码,并依靠编译器来抵消性能问题.我想在没有模板的情况下做类似的事情 - 比如说,因为它们太难以处理或因为你使用普通的C.

您可以将所有代码写入一个文件中.那太可怕了.如何编写脚本,将所有代码合并到一个源文件中并编译它?要求您的源文件写得不是太多.然后编译器可能会应用更多优化(内联,死代码编译,编译时算术等).

你对这个"诡计"有任何经验或反对意见吗?

Cat*_*lus 8

使用现代编译器毫无意义.MSVC,GCC和clang都支持链接时代码生成(GCC和clang称之为'链接时优化'),它允许这样做.此外,将多个翻译单元组合成一个大型文件会使您无法并行化编译过程,并且(至少在C++的情况下)使RAM使用率达到顶峰.

在每个翻译单元中,您包括一般,灵活结构的所有代码,并依靠编译器来抵消性能问题.

这不是一个功能,它与任何方式的性能无关.这是编译器和包含系统的烦人限制.


Eri*_*rik 5

这是一种半有效的技术,在大多数人拥有一个 cpu核心的那一天,iirc KDE用它来加速编译.但是有一些警告,如果你决定做这样的事情,你需要记住你的代码.

一些需要注意的事项样本:

  • 匿名命名空间 - namespace { int x; };在两个源文件中.
  • 使用 - 声明影响以下代码.using namespace foo; 在.cpp文件中可以没问题 - 附加的来源可能不同意
  • 匿名命名空间的C版本,静态全局变量.static int i;在几个cpp文件的文件范围将导致问题.
  • #define在.cpp文件中 - 将影响不期望它的源文件

现代编译器/链接器完全能够跨翻译单元进行优化(链接时代码生成) - 我认为使用这种方法你不会看到任何明显的差异.