strace
,但它仅停留在cc1plus
上; 当我使用-f
选项时,我仍然无法找出问题所在。
我已经确定了问题。以下是如何重现它。我编写了一个非常简单的程序,如下所示:
void func_01(int i)
{
int j;
volatile int *jp;
jp = &j;
for (; i; i--) ++*jp;
}
void call_01(void)
{
func_01(10000);
}
int main(int argc, char *argv[])
{
call_01();
}
然后,我复制了它,删除了主要部分并替换了逐渐增加的数字,共进行了999次。然后我构建了:
% time g++ -c test*.cpp
real 0m18.919s
user 0m10.208s
sys 0m5.595s
% cat test*.cpp > mon.cpp
% time g++ -c mon.cpp
real 0m0.824s
user 0m0.776s
sys 0m0.040s
因为我计划扩展到比这更加复杂的数百个文件,所以降低构建时间非常重要。有没有人能够帮忙解释一下这是为什么,或者提供一个不那么粗糙的解决方法?我认为这与预处理器和包含保护所带来的节约有关,因为如果我包括一个文件,时间差异会显著增加(在一个案例中增加了五倍),但如果不包括,则使用单体文件仍然比它快 20 倍。
g++ 的版本是 4.4.2,但我检查了最新版本 8.2.0,结果也存在这个问题。
call_01()
和func_01(int i)
之外没有使用任何东西,因此它可以优化掉所有其他代码。在多文件方法中,它无法这样做。所以它必须为所有代码生成代码,然后将其留给链接器决定哪些内容进入二进制文件。 - NathanOliver$(CXX) $(CPPFLAGS) $(DEFINES) -c src/stdafx.hpp -o $(OBJ)/stdafx.hpp.gch
和$(OBJ)/%.o: src/%.cpp $(CXX) $(CPPFLAGS) $(DEFINES) -iquoteobj$(OBJ)/stdafx.hpp.gch -c $< -o $@
在你的make文件中。这是一个示例make文件。 - Victor Gubinmake -j <N>
命令进行编译,其中 N 为并行进程数。CPU 核心数(超线程的线程数)是选择此参数的好方法,例如make -j 8
。但在重新编译头文件的情况下,必须首先编译它,然后再编译其他文件,因此make -j <N>
可能与此选项不兼容,因为没有任何排序保证。这种构建还可能会使您的系统长时间使用 100% 的 CPU 使用率。 - Victor Gubin