I'm experiencing a strange issue when I try to compile two source files that contain some important computing algorithms that need to be highly optimized for speed.
当我尝试编译两个包含一些需要针对速度进行高度优化的重要计算算法的源文件时,我遇到了一个奇怪的问题。
Initially, I have two source files, let's call them A.c
and B.c
, each containing multiple functions that call each other (functions from a file may call functions from the other file). I compile both files with full speed optimizations and then when I run the main algorithm in an application, it takes 900 ms to run.
最初,我有两个源文件,让我们称它们为A.c和B.c,每个文件包含多个相互调用的函数(文件中的函数可以调用另一个文件中的函数)。我使用全速优化编译这两个文件,然后当我在应用程序中运行主算法时,运行需要900毫秒。
Then I notice the functions from the two files are mixed up from a logical point of view, so I move some functions from A.c
to B.c
; let's call the new files A2.c
and B2.c
. I also update the two headers A.h
and B.h
by moving the corresponding declarations.
然后我注意到两个文件中的函数从逻辑的角度来看是混合的,所以我将一些函数从A.c移到B.c;让我们调用新文件A2.c和B2.c.我还通过移动相应的声明来更新两个标题A.h和B.h.
Moving function definitions from one file to the other is the only modification I make!
将函数定义从一个文件移动到另一个文件是我做的唯一修改!
The strange result is that after I compile the two files again with the same optimizations, the algorithm now takes 1000 ms to run.
奇怪的结果是,在我使用相同的优化再次编译两个文件之后,算法现在需要1000毫秒才能运行。
What is going on here?
这里发生了什么?
What I suspect happens: when functions f
calls function g
, being in the same file allows the compiler to replace actual function calls with inline code as an optimization. This is no longer possible when definitions are not compiled at the same time.
我怀疑发生了什么:当函数f调用函数g时,在同一个文件中允许编译器用内联代码替换实际函数调用作为优化。当定义不是同时编译时,这不再可能。
- Am I correct in my assumption?
- Aside from regrouping the function definitions as it was before, is there anything I can do to obtain the same optimization as before? I researched and it seems it's not possible to compile two source files simultaneously into a single object file. Could the order of compilation matter?
我的假设是否正确?
除了重新组合之前的函数定义之外,我能做些什么来获得与以前相同的优化?我研究过,似乎不可能将两个源文件同时编译到一个目标文件中。编译的顺序是否重要?
1 个解决方案
#1
3
As to whether your assumption is correct, the best way to tell is to examine the assembler output, such as by using gcc -S
or gcc -save-temps
. That will be the definitive way to see what your compiler has done.
至于你的假设是否正确,最好的方法是检查汇编器输出,例如使用gcc -S或gcc -save-temps。这将是查看编译器所做的最终方式。
As to compiling two C source files into a single object file, that's certainly doable. Just create a AB.c
as follows:
至于将两个C源文件编译成单个目标文件,这当然是可行的。只需创建一个AB.c如下:
#include "A.c"
#include "B.c"
and compile that.
并编译。
Barring things that should be kept separate (such as static items which may exist in both C files), that should work (or at least work with a little modification).
除非应该保持分开的东西(例如可能存在于两个C文件中的静态项目),这应该起作用(或者至少可以进行一些修改)。
However, remember the optimisation mantra: Measure, don't guess! You're giving up a fair bit of encapsulation by combining them so make sure the benefits well outweigh the costs.
但是,请记住优化口头禅:措施,不要猜!你通过组合它们放弃了相当多的封装,所以确保好处远远超过成本。
#1
3
As to whether your assumption is correct, the best way to tell is to examine the assembler output, such as by using gcc -S
or gcc -save-temps
. That will be the definitive way to see what your compiler has done.
至于你的假设是否正确,最好的方法是检查汇编器输出,例如使用gcc -S或gcc -save-temps。这将是查看编译器所做的最终方式。
As to compiling two C source files into a single object file, that's certainly doable. Just create a AB.c
as follows:
至于将两个C源文件编译成单个目标文件,这当然是可行的。只需创建一个AB.c如下:
#include "A.c"
#include "B.c"
and compile that.
并编译。
Barring things that should be kept separate (such as static items which may exist in both C files), that should work (or at least work with a little modification).
除非应该保持分开的东西(例如可能存在于两个C文件中的静态项目),这应该起作用(或者至少可以进行一些修改)。
However, remember the optimisation mantra: Measure, don't guess! You're giving up a fair bit of encapsulation by combining them so make sure the benefits well outweigh the costs.
但是,请记住优化口头禅:措施,不要猜!你通过组合它们放弃了相当多的封装,所以确保好处远远超过成本。