【问题标题】:Splitting code into files and O flags将代码拆分为文件和 O 标志
【发布时间】:2016-01-31 07:05:02
【问题描述】:

在编写可以在 C 中并行执行的代码的程序时,我们肯定会使用O flags 来优化代码。

gcc -Olevel [options] [source files] [object files] [-o output file]

在大型项目中,我们通常split the code into several files。我没有找到答案的问题是:

由于我们将代码拆分为文件并且O 标志没有足够的信息来进一步优化,程序的性能是否会下降?有这种可能吗?

【问题讨论】:

  • 如果您将其拆分为包含在#include 中的文件,它无法 产生任何影响。如果你把它拆分成单独编译的组件,我仍然严重怀疑它:编译器优化非常本地化。但我不能说这是事实,所以这不是一个答案......
  • 我已经将个人项目拆分为文件,性能下降了很多。我专门问了一个问题,但我没有回答,所以我删除了它。现在我并不是说这是因为代码拆分而发生的,但我想了解这是否可能,因为对我来说这似乎不太可能。
  • “我并不是说这是因为代码拆分”。您是否只是将项目拆分为单独的文件,仅添加了必要的标头和最少的必要链接器详细信息,还是您也更改了其他条件?
  • 由于我的项目与双音排序的各种实现有关,因此我将每个实现拆分为一个 .c 文件,其各自的头文件用于定义。现在问题来了:当主文件包含头文件并且通过makefile完成编译以分别编译文件时,我得到的性能比直接包含.c文件时要差。我没有更改文件中的任何内容,我只是添加了头文件,其中包含我必须使用的全局变量和函数定义的 extern 声明。

标签: c gcc lto translation-unit


【解决方案1】:

当您将代码拆分为单独的文件时,它可能会将其拆分为多个翻译单元,而编译器通常无法对其进行优化。

以在一个翻译单元中定义但在许多其他翻译单元中引用的常量为例。所有引用常量的计算都必须在运行时执行,因为常量不能在编译时折叠到它们中。

链接时间optimization (-flto) 是绕过限制的一种方法。

【讨论】:

  • 正是我想要的。感谢您的简单解释。
  • @naltipar 没问题,我很高兴能帮上忙。
  • 我在考虑是否应该接受这个答案或我的答案,因为 -flto 不能用于我需要的目的,但通常这是我正在寻找的。最后,我将一劳永逸地接受这个答案,并让我的答案成为一个补充。
  • @naltipar 无论哪种方式都可以。如果您发现 LTO 和 SCU 之间存在回归,则报告它们会有所帮助,因为 LTO 通常旨在取代 SCU。不幸的是,它仅在更新的 GCC 和 Clang 版本中可用。
【解决方案2】:

单机优化

为了补充@Jason 的回答,我想发布另一种技术来避免拆分文件时出现的限制。

它叫Single Unit Optimization

单一编译单元技术使用预处理器指令在编译时而不是链接时将不同的翻译单元“粘合”在一起。由于消除了重复,这减少了总体构建时间,但增加了增量构建时间(对单个编译单元中包含的任何单个源文件进行更改后所需的时间),因为需要如果任何单个输入文件发生更改,则完全重建整个单元。

整个项目,即使分割成文件,也可以优化,就好像程序的所有部分对编译器都是可见的,而无需用户再次合并文件。

如何申请?

通常,该项目将包含一个带有 main 的文件,并将包含每个拆分文件的所有头文件:

ma​​in.c

#include "sub-program-1.h"
#include "sub-program-2.h"
...
#include "sub-program-n.h"
//rest of code

每个.h 文件对应于其各自的.c,后者是自行编译的(可能通过makefile)。

为了应用 SCU,我们删除了我上面提到的包含,而是创建了一个新文件(我们称之为 SCU.c)。这将是以下内容。

SCU.c

#include "sub-program-1.c"
#include "sub-program-2.c"
...
#include "sub-program-3.c"
#include "main.c"
//no more code in this file

而要编译整个项目,我们只需编译SCU.c

【讨论】:

  • 请注意,LTO 旨在取代 SCU(统一构建)。
猜你喜欢
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多