4

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

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

到目前为止,一切都很好?

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

假设一个多编译单元程序需要几分钟来编译,而重新配置为单个编译单元的同一程序需要几个小时来编译......如果单个编译单元将所有函数声明为内联,从而提供更多优化机会,对我来说,期望执行时间可以减少几个百分点似乎是合理的,而不是弥补额外的编译时间。

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

4

3 回答 3

2

Some compilers/linkers are able to automatically inline functions even when they are defined in one compilation unit and used in another. Microsoft's linker can certainly do this.

To me the main benefit of splitting code into separate compilation units is the overall organization of the code and I always make decisions based on this fact rather than the considerations you have. Also don't forget that larger programs are often worked on by more than one person at a time. Obviously separate compilation units is a great benefit then.

In short I think it's heavily situation dependent. I think your situation is a rare one however.

于 2012-07-26T06:24:56.263 回答
2

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

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

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

于 2012-07-26T06:55:24.417 回答
0

不要忘记 80-20 规则。80% 的程序运行时间用在 20% 的代码中。也许您可以将这 20% 放在一个编译单元中,而其余的则组织良好?

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

于 2012-07-26T06:35:40.667 回答