38

我有大约 50 个不同的静态库链接到我的 c++ 项目中,链接平均需要 70 秒。

我发现这次库的链接顺序发生了变化。这是可以预料的,我猜如果链接器不必在它建立的整个符号表中继续搜索一组符号。

我想我可以使用“nm”来获取静态库之间的依赖关系图。但是,这只会给我一个“正确”的链接顺序。获得最快链接顺序涉及哪些因素?

我觉得它与上述依赖关系图有关,方法是通过遍历尝试最小化一些数量,但我真的不确定是哪个。

任何帮助,将不胜感激。

我主要使用 intel 编译器和 gcc 编译器。当我用 top 检查它时,它们似乎都在使用 GNU ld 链接器。希望这可以帮助...

因此,为了进一步澄清我要问的问题,我已经知道如何从一组静态库中获得 1-pass ordering。我自己编写了这个脚本,但正如奥拉夫在下面的回答所暗示的那样,有众所周知的工具可以做到这一点。

我的问题是,我已经有两个 1-pass 链接排序,其中一个在 ~85 秒内运行,另一个在 ~70 秒内运行。很明显,我们仍然可以在 1-pass 订单中进行更多优化。

4

4 回答 4

7

作为替代方案,为什么不尝试将您的库编译为共享库而不是静态库呢?

在我工作的地方,一个大型项目的链接时间约为 6 分钟,这仅适用于 5 个库!

我的解决方案是(对于调试版本),按字母顺序创建 .so 文件(libA.so、libB.so 等),这样每个单独的链接都不会太长,最终链接要短得多,因为所有(部分)链接以前做过。发布版本是以老式方式构建的,因为我的新方法存在感知“危险”。

使用这种方法,我设法将 1 个模块的编译/链接周期从 6 分钟缩短到 10 秒。

于 2013-03-06T22:48:33.720 回答
6

过去,静态库中对象的顺序很重要。您可以使用以下方法对对象进行相应的排序:

$ 领主 *.o | 排序

也许你可以对你的主要对象和库做同样的事情,例如lorder main.o test.o libsome.a libthing.a | tsort. 看男主

于 2012-11-13T20:00:10.593 回答
3

根据比较 ld 和 gold的信息,ld 的速度受符号表大小的影响。随着符号表从处理目标文件中增长,链接步骤变得越慢。因此,如果您有两个不同的 1-pass 链接顺序,则将具有大量符号的库按该顺序稍后修复的那个应该链接得更快。您应该能够修改拓扑排序以在排序标准中包含符号计数。

于 2012-11-14T02:26:07.417 回答
3

您说的是基于对象和库的顺序的一次性排序,但是如果它正在通过静态库进行搜索,则不能保证静态库中的任何内容都将以任何特定的顺序排列,实际上您只能控制它通过以某种方式订购静态库ar

此外,在不了解链接器如何使用静态库(y|ies)的情况下,可以做出的两个最佳假设是:

  1. 它创建一个符号哈希表,引用提供或需要它们的对象;如果这是一个准确的假设,那么您可以在静态库上获得的最佳下限是填充此类哈希表并从中读取所需的时间。
  2. 它根据存档索引中给出的顺序盲目地从存档中读取。

作为尝试找到最佳链接时间的下限,请尝试将存档中的所有或部分对象链接为可重定位对象;对于子集,如果可能,识别所有实际链接的对象。

的手册页lorder表明您可以使用ar ts <archive>... 获得相同的结果,这将为您打印有序列表。的手册页ar似乎表明ar使用该s标志运行将自动将该最佳排序存储在存档的索引中。

另外,请注意可能存在循环依赖关系,但如果您已经搞砸了,tsort您应该已经意识到这一点。

最后,我将留给您最后一条信息。您想要的是可以解决 NP 完全问题的东西。祝你好运。


最近一段时间,我一直在为我正在处理的构建运行一些时间测试;我已经将s标志添加到我ARFLAGS的,看看它有什么效果。

总的来说,它似乎增加了我的构建时间,但我相信有一个合乎逻辑的解释:

  • 大多数可执行文件/共享对象不使用静态链接
  • 它正在构建每个静态库的 PIC 和非 PIC 版本

如果我们更多地使用静态库,我们可能会看到这样做的好处。

于 2013-03-07T17:54:32.140 回答