如何确定最快的链接顺序?

时间:2012-11-13 19:28:41

标签: c++ performance linker ld

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

我发现这次移动了库的链接顺序。这是预期的,我想如果链接器不必在它构建到该点的整个符号表中继续搜索一组符号。

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

我感觉它会与上面提到的依赖图有关,通过尝试最小化一些数量的遍历,但我真的不确定哪个。

任何帮助将不胜感激。

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

所以只是为了澄清我想要问的内容,我已经知道如何从一组静态库中获得1遍的排序。我自己编写了这个脚本,但正如Olaf的回答所示,有一些众所周知的工具可以做到这一点。

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

4 个答案:

答案 0 :(得分:7)

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

在我工作的地方,一个大项目的链接时间大约是6分钟,这只适用于5个图书馆!

我的解决方案是(对于调试版本),按字母顺序创建.so文件(libA.so,libB.so等),因此每个单独的链接不会太长,最后的链接要短得多,因为所有(部分)之前已经完成了联系。发布版本是以老式的方式构建的,因为我的新方法存在“危险”。

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

答案 1 :(得分:6)

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

  

$ lorder * .o | tsort的

也许您可以对主要对象和库执行相同操作,例如: lorder main.o test.o libsome.a libthing.a | tsort。看man lorder

答案 2 :(得分:3)

根据信息comparing ld to gold,ld的速度受符号表的大小影响。随着符号表从处理对象文件增长,链接步骤变得越慢。因此,如果您有两个不同的1遍链接顺序,那么将具有更多数量的符号的库以稍后的顺序进行修复的应该更快地链接。您应该能够修改拓扑排序,以在排序条件中包含符号计数。

答案 3 :(得分:3)

你说的是基于对象和库的顺序的一次通过排序,但是如果它正在通过静态库进行搜索,它不能保证静态库中的任何内容都会以任何特定的顺序排列,事实上你可以只有当你ar时才通过某种方式对静态库进行排序来控制它。

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

  1. 它创建一个符号哈希表,引用提供或需要它们的对象;如果这是一个准确的假设,那么你可以在静态库上获得的最佳下限就是填充这样一个哈希表并从中读取它所需的时间。
  2. 它根据档案索引中给出的顺序盲目地从档案中读取。
  3. 尝试查找最佳链接时间的下限时,请尝试将归档中对象的全部或部分链接为可重定位对象;对于子集,如果可能,识别实际链接的所有对象。

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

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

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


    我一直在运行一些计时测试,我正在进行的构建;我已将s标记添加到ARFLAGS,以查看其效果。

    总的来说,它似乎增加了我的构建时间,但我相信有合理解释原因:

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

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