c++ - 源代码合并真的能提高 C 或 C++ 程序的性能吗?

标签 c++ c gcc compiler-optimization

<分区>

代码合并包括将整个源代码复制到一个文件中。

例如,它是由 SQLite 完成的减少编译时间并提高生成的可执行文件的性能。在这里,它生成一个包含 184K 行代码的文件。

我的问题不是关于编译时间(已在 this question 中回答),而是关于可执行文件的效率。

SQLite 开发者说:

In addition to making SQLite easier to incorporate into other projects, the amalgamation also makes it run faster. Many compilers are able to do additional optimizations on code when it is contained with in a single translation unit such as it is in the amalgamation. We have measured performance improvements of between 5 and 10% when we use the amalgamation to compile SQLite rather than individual source files. The downside of this is that the additional optimizations often take the form of function inlining which tends to make the size of the resulting binary image larger.

据我了解,这是由于 interprocedural optimization (IPO) 造成的,由编译器进行的优化。

GCC开发人员也这样说(感谢@nwp 提供的链接):

The compiler performs optimization based on the knowledge it has of the program. Compiling multiple files at once to a single output file mode allows the compiler to use information gained from all of the files when compiling each of them.

但他们并没有谈到这样做的最终 yield 。

除了 SQLite 之外,是否有任何测量结果证实或反驳了 IPO with 合并产生比 IPO without 合并更快的可执行文件的说法当用 gcc 编译时?

作为附带问题,关于此优化,进行代码合并或将所有 .cpp(或 .c)文件#include 到一个文件中是一回事吗?

最佳答案

源代码文件的组织不会“产生更高效的二进制文件”,并且从多个源文件中检索的速度可以忽略不计。

版本控制系统将deltas 任何文件,无论大小。

通常,像这样的单独组件被单独编译以生成包含相关目标代码的二进制:源代码不会每次都重新编译。当“应用程序 A”使用已更改的“库 B”时,“应用程序 A”必须重新链接,但如果库的 API 未更改,则不必重新编译。

并且,就库本身而言,如果它由(数百个)单独的源文件组成,则在重新链接库之前,只有已更改的文件必须重新编译。 (任何 Makefile 都会执行此操作。)如果源代码是“一件大事”,您每次都必须重新编译所有内容,这可能会花费很长时间 时间...基本上是浪费时间。

有两种方法可以将库中的目标代码(一旦它被构建......)合并到可执行文件中:静态链接和动态。 如果使用静态链接,库的必要 部分将被复制到可执行文件中……但不是全部。运行可执行文件时,不必存在库文件。

如果使用动态链接,整个库将存在于一个单独的文件中(例如 .DLL.so),它确实必须在运行时出现,但将由同时使用它的每个应用程序共享。

我建议您主要将此视为源代码管理问题,而不是会带来任何技术或运行时优势的问题。 (不会。)我发现很难找到这样做的令人信服的理由。

关于c++ - 源代码合并真的能提高 C 或 C++ 程序的性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38899001/

相关文章:

.net - 如何在您自己的 C++ 项目中包含外部库?

c++ - 更改运行时库破坏了 std::string。为什么?

c - 如何使用C中的直接 header 扫描文件夹中的文本

c++ - Valgrind 声称内存释放中有太多释放

c++ - 编译一个相当简单的c++ 11程序时gcc和clang之间的不同结果

c++ - 旋转立方体,使正面保持正方形

c++ - 赋值运算符与自定义构造函数的关系

c - C 中的 TCP 服务器 - 端口总是在增加?

c++ - 如何理解独立 C 或 C++ 实现中的原子?

c++ - const_reference_type 不编译但 const value_type& 编译