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

C++ 如何确定最快的链接顺序?,c++,performance,linker,ld,C++,Performance,Linker,Ld,我有50个不同的静态库连接到我的C++项目中,链接平均使用70s。p> 我发现,这次随着库的链接顺序的改变而改变。如果链接器不必在整个符号表中一直搜索一组符号,我猜这是意料之中的 我想我可以使用“nm”来获得静态库之间的依赖关系图。然而,这只会给我一个“正确”的链接顺序。获得最快链接订单涉及哪些因素 我觉得这与上面提到的依赖关系图有关,通过遍历可以尽量减少一些数量,但我真的不确定是哪个 任何帮助都将不胜感激 我主要使用英特尔编译器和gcc编译器。当我用top检查GNULD链接器时,他们似乎都在使

我有50个不同的静态库连接到我的C++项目中,链接平均使用70s。p> 我发现,这次随着库的链接顺序的改变而改变。如果链接器不必在整个符号表中一直搜索一组符号,我猜这是意料之中的

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

我觉得这与上面提到的依赖关系图有关,通过遍历可以尽量减少一些数量,但我真的不确定是哪个

任何帮助都将不胜感激

我主要使用英特尔编译器和gcc编译器。当我用top检查GNULD链接器时,他们似乎都在使用GNULD链接器。希望这有助于

所以,为了进一步澄清我想问的问题,我已经知道如何从一组静态库中获得一个1-pass排序。我自己写了这个脚本,但正如奥拉夫在下面的回答所暗示的,有一些众所周知的工具可以实现这一点


我的问题是,我已经有两个单通链路订购,其中一个在85秒左右运行,另一个在70秒左右运行。所以很明显,我们还可以在单次订单内进行更多优化

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

$lorder*.o|tsort


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

根据信息,ld的速度受符号表大小的影响。随着符号表从处理对象文件开始增长,链接步骤变得越慢。因此,如果您有两个不同的单次链接顺序,则将具有更多符号的库按该顺序稍后修复的顺序放置的链接应该更快。您应该能够修改拓扑排序,以便在排序条件中包含符号计数。

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

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

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


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

您所说的是基于对象和库的顺序的一次性排序,但是如果它在一个静态库中搜索,它不能保证静态库中的任何东西都是以任何特定的顺序进行的,事实上,您只能通过在
ar
it时以某种方式对静态库进行排序来控制它

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

  • 它创建一个符号哈希表,引用提供或需要符号的对象;如果这是一个准确的假设,那么静态库的最佳下限是填充此类哈希表并从中读取所需的时间
  • 它根据存档索引中给出的顺序盲目地从存档中读取
  • 为了找到最佳链接时间的下限,请尝试将存档中的所有对象或对象子集链接为可重定位对象;对于子集,如果可能,请标识实际链接的所有对象

    lorder
    的手册页表明您可以使用
    ar ts
    获得相同的结果。。。它将为您打印订购的列表。
    ar
    的手册页似乎表明运行带有
    s
    标志的
    ar
    将自动将该最佳顺序存储在存档的索引中

    此外,请注意可能存在循环依赖关系,不过如果您已经处理了
    tsort
    ,您应该已经知道了这一点

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


    在过去的一段时间里,我一直在为一个构建运行一些计时测试;我已将
    s
    标志添加到我的
    ARFLAGS
    中,以查看其效果

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

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

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

    可能是符号/未解析符号列表,但这更多的是直觉而非知识。旁注:您必须说明您感兴趣的链接器,因为不同的链接器有完全不同的行为(例如,ibm在库列表上迭代多次,直到它解决了所有问题或取得了进展),我确实说明了我正在使用英特尔编译器套件,因此这将是错误的(至少当我检查top时,它似乎正在运行ld)。我偶尔也会使用gcc编译器套件,所以这也是ld。这只是一个粗略的想法:编写一个脚本来排列库的所有可能顺序,并以编程方式测量链接时间。@g-makulik我提到过我有50个库,链接时间约为70秒吗?假设你这样做不是为了