【问题标题】:how to find the bottleneck in linking?如何找到链接的瓶颈?
【发布时间】:2026-02-20 13:00:01
【问题描述】:

我有一个链接速度很慢的项目(~ 2 分钟,我觉得这很慢)。 我知道更快的链接器,例如 gold 或 lld,但我无法更改链接器。

我在我的代码中使用了很多 C++11 模板,我怀疑某些模板代码可能会在多个目标文件中重复实例化,但我不知道如何确定这是否属实。

我想知道是否有一种方法来分析整个链接阶段,就像我们分析程序并试图找到瓶颈一样。例如,我可以使用一个工具来检查如何很多时候,一个符号(不必要地)出现在不同的目标文件中,然后在链接过程中被丢弃,这可以帮助我找出可能是哪个模板代码导致的。以上关于目标文件中的重复符号只是我的猜测 - 我需要一个基于证据的方法。 然后基于这个发现,我将考虑如何改进我的代码以减少链接时间。

我使用 CMake、GNU g++ 和 ld 作为我的构建工具,并且我在 Linux 平台上工作。

谢谢。

【问题讨论】:

  • 抱歉,关于工具的问题是题外话。不过,您可能会发现 github.com/adrianstone55/SymbolSort 很有用。
  • @MaxLanghof 寻求工具建议是题外话,就单个特定工具寻求特定帮助是可以的。
  • 使用“显式模板实例化”有时会有所帮助。您可能还会发现以下内容:randomascii.wordpress.com/2014/03/10/making-compiles-slow
  • @JesperJuhl 感谢您的链接,但我有太多模板类/函数无法显式实例化,我什至不确定这是否是链接缓慢的原因!这就是为什么我想要一种基于证据的方法——它真的是由模板引起的吗?如果是,罪魁祸首是哪个类/函数?
  • 减少链接时间的技术将特定于您的编译器和链接器,并且通常会通过导致更大的增量编译时间来减少链接时间来进行权衡。一些技术,例如显式模板实例化,也会影响开发/维护工作。不过,两分钟的链接时间表明了一个非常小的项目 - 只需以此为借口伸展双腿,或到户外重新将注意力从屏幕上移开。

标签: c++ gcc linker ld


【解决方案1】:

解决此问题的一种方法是转储包含在nm --demangle --defined-only --extern-only 链接中的每个目标文件和存档的定义符号,并构建映射{symbol, definition_count}。将此映射按definition_count 从高到低排序并打印。

【讨论】: