【问题标题】:How to link with the GNU gold linker instead of ld in Haskell如何在 Haskell 中使用 GNU 黄金链接器而不是 ld 链接
【发布时间】:2017-08-31 18:49:10
【问题描述】:

我的 Haskell 项目在Linking dist/build/myapp/myapp ... 上花费了大量时间,并且在执行TemplateHaskell 代码时还用于加载共享库。

我怀疑这是因为ld 很慢。

如何通过切换到gold 链接器来缩短链接时间?

【问题讨论】:

  • 除了切换链接器,您还可以使用-dynamic 标志。它可以轻松地将链接速度提高十倍。
  • @vshabanov 真的是这样吗?我过去曾尝试使用动态链接,但它并没有让我的整个 cabal 项目变得更快。但我可能做错了什么,所以它使用了-dynamic-too,给了我静态库和动态库。如果有一个最小的示例项目来展示它是否真的让它更快,那就太好了。
  • 您应该只使用-dynamic GHC 选项。 -dynamic-too同时链接静态(缓慢、大的可执行文件)和动态(较小的可执行文件,更快的链接时间),因此您不会获得任何加速。
  • @vshabanov 在 Linux 上。我有大约 30 GB 的可用 RAM。这不是缓存问题,它会在后续启动时发生;花费的时间是 ld-linux 动态链接器/加载器中花费的 100% 用户 CPU 时间。 This page 同意这种现象:The runtime performance costs of dynamic linking are substantial compared to those of static linking。请注意,我在 lld 中有 100 个条目。关于加速,链接时间似乎从每个可执行文件的 2.5 秒下降到 1.5 秒,但这对我来说不值得增加启动时间。
  • 我发现this useful comment 表明通过设置-fvisibility=hidden 并手动导出所有导出的符号可以显着提高动态链接速度。也许可以通过使用它来改善动态加载启动时间。

标签: haskell linker gold-linker


【解决方案1】:

使用gold 链接速度提高 3 倍

Since GHC 7.8,您可以告诉 GHC 和 cabal(在运行时无需重新编译 GHC)与 GNU gold 链接。

您需要在您的.cabal 文件中:

library:
  ghc-options: -optl-fuse-ld=gold
  ld-options:  -fuse-ld=gold

executable myExecutable
  ghc-options: -optl-fuse-ld=gold
  ld-options:  -fuse-ld=gold

(请注意,您可能希望在命令行上将这些标志传递给stack/cabal/Setup.hs,而不是将它们硬编码在 .cabal 文件中,以免降低包的可移植性。)

对我来说,3.5x 更快,将项目的总链接时间从 150 秒缩短到 40 秒。


更新:使用lld 链接速度提高 10 倍

完整示例请参见https://github.com/nh2/link-with-lld-example;关键部分:

library
  ghc-options: "-pgmP clang" "-pgmc clang" "-pgma clang" "-pgml clang" "-optl-fuse-ld=lld"
  ld-options:  -fuse-ld=lld

executable myExecutable
  ghc-options: "-pgmP clang" "-pgmc clang" "-pgma clang" "-pgml clang"
  ld-options:  -fuse-ld=lld

我的项目的最终可执行链接时间的链接时间比较:

ld   124 seconds
gold  36 seconds
lld   11 seconds

【讨论】:

  • 你的项目有多大,如果你不介意我问的话?
  • @jberryman 不是很大,150 个 Haskell 模块和 8 个由它们构建的可执行文件。但这取决于(和链接)几个本地库,例如 opencv。使用ld,每个库链接大约需要 20 秒。
  • 通过在 489 个模块和 13 个可执行项目(包括测试和基准测试)上将时间缩短 40 秒来确认构建速度。
  • @SebastianGraf 它不适用于 lld 开箱即用,至少不适用于我提供的选项,因为(至少在我的系统上)通过调用 gcc 和 gcc 链接是not (yet) compatible with lld。您必须告诉 ghc 使用 clang 工具链而不是 gcc;我还没有尝试过。不过,我很想知道标志是什么。
  • @unhammer 不一定有效; lld 不接受ld 接受的所有标志,并且官方gcc(GHC 默认调用链接)不支持与lld 链接。 (你的意思是lld,而不是ldd——之所以这么说是因为这个错字实际上会让人感到困惑,因为两者都在链接相关程序)。
猜你喜欢
  • 2017-04-18
  • 2015-08-17
  • 2016-10-02
  • 2017-12-12
  • 2017-03-25
  • 2015-09-07
  • 1970-01-01
  • 2016-11-27
  • 1970-01-01
相关资源
最近更新 更多