当(执行时间)>>>时,多个编译单元仍然值得(编译时间)?

时间:2012-07-26 06:17:27

标签: c++ compilationunit

根据我的理解,创建具有多个编译单元的程序的主要好处是组件的可重用性以及在合并小的更改时缩短编译时间。

我也认为(可能错误地)存在与此相关的惩罚,因为在他们自己的编译单元中定义的函数不能被声明为“内联”。
[我认识到这个关键字实际上不会强制编译器内联扩展函数,但我的理解是它为编译器提供了更大的优化灵活性,因此值得尽可能包括在内。]

到目前为止一直很好?

我真正的问题是,当程序解决复杂的建模问题时,成本/收益分析是否仍然支持多个编译单元,并且需要在集群上迭代其主循环数月才能生成有用的输出。 / p>

假设多编译单元程序需要几分钟才能编译,而同一个程序重新配置为单个编译单元需要几个小时来编译...如果单个编译单元将所有函数声明为内联并因此呈现更多的优化机会,我认为执行时间可能会减少几个百分点,而不是弥补额外的编译时间,这似乎是合理的。

对于这样的情况,是否有良好的经验法则,或者是否严重依赖于情境?

3 个答案:

答案 0 :(得分:2)

某些编译器/链接器能够自动内联函数,即使它们在一个编译单元中定义并在另一个编译单元中使用。微软的链接器当然可以做到这一点。

对我来说,将代码拆分为单独的编译单元的主要好处是代码的整体组织,我总是根据这个事实做出决定,而不是考虑你的考虑因素。另外,不要忘记,较大的程序通常一次由多个人处理。显然,单独的编译单元是一个很大的好处。

简而言之,我认为这取决于情况。我认为你的情况很罕见。

答案 1 :(得分:2)

正如其他人所说,将程序分解为不同的编译单元的主要好处是可读性。 较短的编译时间在某种程度上是一个很好的副作用。

如果您关心内联,可以诉诸Link Time Code Generation and Link-Time Optimization。程序分解到编译单元和LTO的组合看起来像是理想的解决方案,尽管尚不清楚当函数的完整定义可用时编译器执行的优化类型是否可以由LTO执行。 例如,我不知道LTO是否可以支持C ++中的返回值优化,因为它是在高抽象级别完成的。需要进行性能测试。 (编辑:即使没有LTO和类似的高级技巧也会执行RVO,至少在gcc和clang上[我试过]。很可能,这个优化是通过改变函数的ABI来执行的,它将一个“隐藏指针”带到必须在函数中构造和返回的对象。)

第三个可能值得研究的解决方案是使用类似sqlite amalgamation的东西,这是一个将不同的编译单元放入一个巨大的.c文件的过程。 看起来像需要一个沉重的用户制造基础设施的东西,但是。

答案 2 :(得分:0)

不要忘记80-20规则。 80%的程序运行时花费在20%的代码中。也许你可以在一个编译单元中拥有20%,其余的组织良好?

关于源组织,您仍然可以将算法放入标题(作为模板或内联函数),然后从它们组成源。