如何在Haskell中使用GNU gold链接器而不是ld链接器

37

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

我怀疑这是因为 ld 太慢了。

如何通过切换到 gold 链接器来提高链接时间呢?


除了切换链接器,您还可以使用“-dynamic”标志。它可以轻松地将链接速度提高十倍。 - vshabanov
@vshabanov 这是实际情况吗?我曾经尝试过使用动态链接,但并没有使整个 cabal 项目更快。但我可能做错了什么,以至于它同时给我提供了静态和动态库。如果有一个最小的示例项目可以展示它是否真的可以加速,那将是很好的。 - nh2
@vshabanov 我现在尝试了动态链接可执行文件,但它们对我来说不是一个好选择,因为由于运行时链接,我的可执行文件的启动时间(仅用于“--help”文本)从静态方式的160毫秒增加到了4.5秒。我现在将坚持使用静态链接。 - nh2
1
@vshabanov 在Linux上,我有大约30GB的可用内存。这不是缓存问题,在后续启动时仍然会发生;它所花费的时间是100%的用户CPU时间在ld-linux动态链接器/加载器中消耗。这个页面证实了这种现象:与静态链接相比,动态链接的运行时性能成本相当高。请注意,我在lld中有数百个条目。关于加速,链接时间似乎已经从每个可执行文件2.5秒降至1.5秒,但对我来说,这并不值得增加启动时间。 - nh2
1
我发现这个有用的评论,建议通过设置-fvisibility=hidden并手动导出所有导出符号,可以大大提高动态链接速度。也许使用它可以改善动态加载启动时间。 - nh2
显示剩余2条评论
1个回答

47

使用gold,让链接速度提升3倍

自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.5倍,将一个项目的总链接时间从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

2
请问一下,你的项目有多大? - jberryman
2
@jberryman 不是很大,包含150个Haskell模块和由它们构建的8个可执行文件。但它依赖于(并链接)一些本机库,如OpenCV。使用ld命令进行每个库链接几乎需要20秒。 - nh2
2
通过在包括测试和基准测试的489个模块和13个可执行文件项目中减少40秒的时间,确认构建速度提高。 - Shersh
1
@unhammer 这并不一定有效;lld 不接受 ld 所有的标志,而且官方上 gcc(GHC 默认用于链接的程序)不支持使用 lld 进行链接。 (还有你应该是指 lld 而不是 ldd -- 只是提醒因为这个打字错误实际上可能会让人感到困惑,因为两者都是与链接相关的程序)。 - nh2
1
@jberryman 我想你是指 gcc 10 而不是 ghc 10?我需要检查现在可以删除什么,但还没有时间。此外,现在已经有一个新的、更快的链接器可用了: mold - nh2
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接