25

我们有相当大的 C++ 应用程序,它在 Visual Studio 2005 中由大约 60 个项目组成。目前在发布模式下链接需要 7 分钟,我想尽量减少时间。有什么改善链接时间的技巧吗?

大多数项目都编译成静态库,这使得测试更容易,因为每个项目都有一组相关的单元测试。似乎静态库的使用阻止了 VS2005 使用增量链接,因此即使打开了增量链接,它每次都会执行完整链接。

对子项目使用 DLL 会有什么不同吗?我真的不想浏览所有标题并添加宏来导出符号(即使使用脚本),但如果它可以减少 7 分钟的链接时间,我肯定会考虑它。

由于某种原因,从命令行使用 nmake 会稍微快一些,并且在 Linux(使用 GCC)上链接相同的应用程序要快得多。

  • Visual Studio IDE 7 分钟
  • 从命令行使用 nmake 的 Visual C++ - 5 分钟
  • Linux 上的 GCC 34 秒
4

15 回答 15

19

如果您使用该/GL标志来启用整体程序优化 (WPO) 或使用该/LTCG标志来启用链接时间代码生成,关闭它们将显着改善链接时间,但会牺牲一些优化。

此外,如果您使用该/Z7标志将调试符号放入.obj文件中,则您的静态库可能很大。如果它阻止链接器从磁盘读取所有调试符号,则使用/Zi创建单独的文件可能会有所帮助。.pdb我不确定它是否真的有帮助,因为我没有对它进行基准测试。

于 2008-09-28T06:54:48.483 回答
13

请参阅我在 Microsoft 提出的建议:https ://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=511300

你应该投票给它!这是我对它的最后评论:

是的,我们正在使用增量链接来构建我们的大部分项目。对于最大的项目,它是没有用的。事实上,使用增量链接将这些项目链接起来需要更多时间(2min50 与 2min44 相比)。我们观察到当 ILK 文件的大小很大时它不起作用(我们最大的项目在 win 32 中生成 262144 KB 的 ilk)。

贝娄,我列出了我们试图减少链接时间的其他事情:

  • 显式模板实例化以减少代码膨胀。小收获。
  • IncrediLink(IncrediBuild 为编译提供了有趣的收益,但对链接几乎没有收益)。
  • 删除很少调试的库的调试信息(良好的增益)。
  • 在 « Pre-Build Event » 中删除 PDB 文件(奇怪的是,它给出了有趣的增益,例如:2min44 而不是 3min34)。
  • 将许多静态库转换为 DLL。重要收获。
  • 使用配备大量 RAM 的计算机以最大化磁盘缓存。最大的收获。
  • 大 obj 与小 obj。没有不同。
  • 更改项目选项(/Ob1、/INCREMENTAL、启用 COMDAT 折叠、嵌入清单等)。有些会带来有趣的收获,有些则不会。我们试图不断地最大化我们的设置。
  • 最大化内部链接与外部链接。这是一个很好的编程习惯。
  • 尽可能多地分离软件组件。您可以在单元测试中快速工作。但是我们仍然必须将事物交互在一起,我们有遗留代码并且我们使用第三方组件。
  • 使用秘密链接器开关 /expectedoutputsize:120000000。小收获。

请注意,对于我们所有的实验,我们都仔细测量了链接时间。缓慢的链接时间会严重降低生产力。当您实现复杂的算法或跟踪困难的错误时,您希望快速迭代这个序列:修改一些代码,链接,跟踪调试,修改一些代码,链接等......

优化链接时间的另一点是它对我们的持续集成周期的影响。我们有许多共享公共代码的应用程序,并且我们正在其上运行持续集成。我们所有应用程序的链接时间是周期时间的一半(15 分钟)...

在线程https://blogs.msdn.microsoft.com/vcblog/2009/09/10/linker-throughput/中,提出了一些有趣的建议来改善链接时间。在 64 位计算机上,为什么不提供完全在 RAM 中处理文件的选项?

同样,欢迎任何可以帮助我们减少链接时间的建议。

于 2009-11-20T19:31:13.383 回答
5

通常,使用 DLL 代替静态库会大大缩短链接时间。

于 2008-09-27T15:40:21.257 回答
4

看看Xoreax 的Incredibuild。它的分布式编译大大减少了我们完整的构建/链接时间,从大约 40 分钟到 8 分钟。

此外,该产品具有他们称为Incredilink的功能,它可以帮助您获得增量链接,即使使用静态链接库也是如此。

于 2008-09-27T16:01:49.723 回答
2

我不认为转换为 DLL 会有用。您可以尝试寻找与优化有关的选项,然后将其关闭。链接器可能会花费很长时间查看库中可以消除的冗余代码。您的应用程序最终可能会变大或变慢,但这对您来说可能不是问题。

于 2008-09-27T15:37:34.680 回答
2

有几个人报告(我自己也注意到)在静态链接库中修改文件将禁用整个解决方案的增量链接;这似乎是您所看到的。有关这方面的一些信息,请参阅此处此处的评论。

一种解决方法是使用快速解决方案构建插件。这可能涉及对您的工作空间进行一些更改,但回报绝对值得。对于商业解决方案,请使用 Xoreax 的Incredibuild,它基本上采用了相同的技术,但也添加了其他功能。如果我听起来像 Incredibuild 的推销员,我深表歉意——我只是一个非常满意的客户。

于 2008-09-27T20:13:12.880 回答
2

我以前在将大型应用程序与 Visual C++ 链接时也遇到过类似的问题。就我而言,我根本没有足够的可用 RAM 并且过多的磁盘分页导致链接过程停止。将我的内存从 1GB 翻倍到 2GB 取得了显着的进步。你的开发箱运行了多少?

于 2008-09-28T04:05:26.300 回答
2

我刚刚发现我们偶然在一个头文件中定义了一个大的字符串表,它几乎包含在每个(静态)库中。(我说的是一个巨大的 C++ 项目。)当链接器创建 EXE 时,它看起来像是表格的统一(EXE 中只有一个结尾)或库的解析需要很长时间。将表放在一个单独的 C++ 文件中需要花费几分钟在相对较慢的机器上的链接。

不幸的是,除了偶然之外,我不知道如何找到类似的东西。

于 2009-10-26T00:30:30.050 回答
2

对于调试版本,可以使用增量链接,这可以大大缩短链接时间。

可悲的是,有一些陷阱,VS2005 不会警告你。

  • 如果使用静态库,那么在修改静态库的文件部分时增量链接将不起作用。解决方案是将链接器选项“使用库依赖输入”设置为“是”(这与VS2003中的快速解决方案构建相同)

  • 如果使用 pragma-comment-lib 包含 DLL 的 lib,并指定相对路径而不是单独的 lib,则增量链接将停止工作。解决方案是单独指定 lib,并使用链接器选项 LIBPATH 添加额外的 lib-path。

  • 有时 .ilk 文件会损坏(超过 200 MB),然后增量链接器会突然占用正常时间的 10 倍以上。有时它会抱怨 .ilk 文件已损坏,但通常会在几分钟后首先出现。我的解决方案是为“构建事件”->“预链接事件”设置以下命令

    对于 ($(IntDir)*.ilk) 中的 %%f 执行 (如果 "%%~zf" GTR "200000000" (del %%f))

于 2009-11-17T12:56:43.240 回答
1

60 个要链接的库听起来确实很少。这可能是一个极端的措施,但它可能会从根本上加快速度。创建一个包含几个项目的新解决方案,并将现有项目中的所有源代码添加到这些项目中。然后构建并链接它们,只保留小的用于测试。

于 2008-09-27T15:30:19.330 回答
1

获得一台速度更快的具有多个处理器的计算机并启用并行构建(这可能默认情况下处于启用状态)。为了允许最大程度的并行,请确保您的项目依赖项是正确的,并且您没有不必要的依赖项。

于 2008-09-27T15:34:10.490 回答
1

如果您真的在谈论链接时间,那么快速解决方案构建和 Xoreax 之类的东西并不会真正有多大帮助(除了可能的 Incredilink)。假设您真正测量的是链接开始到链接结束,那么我建议您拥有的库数量是问题所在。

至少在最初,链接阶段在加载所有对象和 lib 文件时是 IO 绑定的。您可能会遇到 60 个库以及一些大量 .obj 文件的主项目的情况。我怀疑您可能至少部分地看到了加载所有这些库和 .obj 文件时典型的 Windows 缓慢。

您可以轻松地对此进行测试。获取所有这些 lib 文件并构建一个单独的 lib 文件作为测试。与其链接其中的 60 个,不如链接一个,看看你的时间都花在了哪里。那会很有趣。

NTFS 是出了名的慢。在 Linux 上它不应该是 7m 对 32 秒慢,但这可能是问题的一部分。使用 DLL 会有所帮助,但您会受到应用程序启动时间的影响,尽管这不会太早。我相信您不会有 7m 的应用程序启动时间。

于 2008-09-28T00:29:22.107 回答
1

你可以试试看这个:http: //msdn.microsoft.com/en-us/library/9h3z1a69.aspx

基本上,如果您有多个内核,您可以并行运行项目构建。

于 2008-09-28T04:08:18.510 回答
1

我已经解决了我的链接问题并分享给大家。

我的项目的链接时间是 7 分钟,使用 /Incremental:no 链接(链接时间 7 分钟)。

使用 /Incremental 时为 15 分钟,(链接时间 7 分钟,嵌入清单时间 7 分钟)。所以我关掉了inremental。

我发现附加依赖项也有 a.lib 并且忽略了特定的库!

所以我从忽略特定库中删除它打开/增量。第一次链接时间需要 5 分钟,但嵌入清单时间没有。

我不知道为什么,但增量链接已经奏效。

我回滚了所有项目代码,所以我可以通过库找到问题。如果你做到了以上所有,你可以试试我的方法。祝你好运!

于 2012-03-16T07:06:27.993 回答
0

C++ 构建时间减少的第 1 步是更多的内存。从 4GB 切换到 12GB 后,我看到我的链接所有项目的时间一落千丈:从 5:50 到 1:15。

于 2012-03-22T17:27:33.557 回答