将源代码组合到单个文件中进行优化

时间:2012-08-15 17:12:00

标签: c optimization

我的目标是减少C项目可执行文件的大小,我尝试了所有编译器/链接器选项,这在某种程度上有所帮助。我的代码包含很多单独的文件。我的问题是,将所有源代码合并到一个文件中是否有助于我想要的优化?我在某处读到,如果编译器在单个文件中找到所有代码而不是单独的多个文件,则会更好地进行优化。这是真的吗?

3 个答案:

答案 0 :(得分:2)

当编译器在同一个可编译(* .c)文件中找到所需代码时,它确实可以更好地进行优化。如果您的程序超过1000行左右,您可能会后悔将所有代码放在一个文件中,因为这样做会使您的程序难以维护,但如果短于500行,您可能会尝试使用一个文件,并且看看它是否有帮助。

关键考虑因素是一个可编译文件中的代码调用或以其他方式使用另一个中定义的对象(包括函数)的频率。如果跨越这个边界的控制转移很少,那么擦除边界将无助于显着性能。因此,在编写性能时,关键是将紧密相关的代码放在同一个文件中。

我非常喜欢你的问题。在我看来,这是一个正确的问题;虽然完整的答案不够简单,无法在Stackexchange答案中完全对待,但您对答案的追求会教会您很多。虽然你可能还没有意识到这一点,但你的问题确实是关于链接,每个高级程序员最终必须学习的主题。您的问题涉及符号表,内联,返回值的就地构造以及其他一些微妙因素。

无论如何,如果您的程序短于500行左右,那么尝试使用单文件方法几乎不会有任何损失。如果超过1000行,则不建议使用单个文件。

答案 1 :(得分:2)

这取决于编译器。例如,英特尔C ++ Composer XE可以自动优化多个文件(使用icc -fast *.c *.cppicl /fast *.c *.cpp构建时,分别用于linux / windows)。

当您使用Microsoft Visual Studio或派生产品(如用于微控制器的Atmel Studio)时,每个源文件都是单独编译的(即一个clicl或{{1为项目中的每个gccc文件发出命令。这意味着没有优化。

对于微控制器项目,我有时必须将所有内容放在一个文件中,以使其甚至适合控制器上有限的闪存。如果您的编译器/ IDE像visual studio一样,您可以使用一个技巧:选择所有源文件并使它们不参与构建过程(但将它们留在项目中),然后创建一个文件(我总是使用{{ 1}}和cpp其中的每个源(即非标头)文件(请注意,包括whole_program.c文件在内的许多高级程序员都不赞同,但有时,你必须这样做肮脏的方式,以及微控制器,实际上往往是这样。)

答案 2 :(得分:1)

我的经验是,使用gnu / gcc,优化在单个文件中,另外还包括创建单个对象。使用clang / llvm这很容易,我建议,不要优化clang步骤,使用clang从C到字节码,使用llvm-link将所有字节码模块链接到一个字节码模块,然后你可以优化整个项目,所有源文件一起优化,同时为目标提供更多优化。你最好的结果是告诉clang使用三重命令行选项,你的最终目标是什么。对于gnu路径来做同样的事情要么使用includes来将一个大文件编译成一个对象,要么除了链接器所做的一些事情之外还有一个机器代码级优化器,那么这就是它必须发生的地方。也许gnu有一个暴露的ir文件格式,优化器和ir目标工具,但我想我现在已经看到了。

http://github.com/dwelch67我的一些项目,虽然非常简单的程序,有相同的源文件的llvm和gnu构建,你可以看到llvm构建的地方我从未优化的字节码和优化的字节码中创建二进制文件(llvm的优化器有小问题循环的问题,有时会产生非工作代码,非常快速检查是否是你或他们是尝试非优化的llvm二进制文件和gnu二进制文件,看看它们是否都表现相同(你)或者如果只有优化的llvm不起作用(它们))。