【问题标题】:Can gcc use multiple cores when linking?链接时gcc可以使用多个内核吗?
【发布时间】:2011-07-05 19:00:48
【问题描述】:

因此,当使用 GCC 编译大量源文件时,可以使用 -j 来使用所有可用的内核。但是链接器呢?是否有类似的选项可以加快链接速度,或者 GCC 不支持多线程?在一些较大的项目中,这确实需要一段时间......(......我讨厌等待!)

编辑:感谢您指出 -j 是 make 而不是 gcc/g++ 的选项。但这并不能回答我的问题!我想知道gcc是否可以在链接一个程序时使用多线程!

【问题讨论】:

  • 您可能对 distcc distcc.org 感兴趣,它允许您在网络中的多台机器上分发编译。
  • @Jon:我对并行编译不感兴趣,但对并行链接感兴趣!
  • 为什么这个问题被否决了?上帝知道 gnu 链接器很慢,找到一些方法让它链接得更快只会改善构建周期。
  • 链接不是一个明显的并行任务。请注意,有时您可以使用可见性属性和/或 -fvisibility gcc 选项来减少链接器的工作。

标签: gcc linker


【解决方案1】:

试试gold,它是由 Ian Lance Taylor 等人开发的。来自 Google 并作为 GNU binutils 软件包的一部分发布。

来自维基百科:

编写 gold 的动机是制作一个比 GNU 链接器更快的链接器,尤其是对于用 C++ 编写的大型应用程序

我必须承认我自己还没有尝试过,但在WebKitGTK project 网页上提到了它。

更多信息见金作者写的一篇文章:A New ELF Linker

更重要的是,请参阅 Sander Mathijs van Veen 关于增量/并行/并发链接的工作,标题为 Concurrent Linking with the GNU Gold Linker 以及其中的参考书目。

【讨论】:

  • 必须强调gold不使用多线程,除非你通过gcc -Wl,--threads -Wl,--thread-count,$(nproc)
【解决方案2】:

lld,LLVM项目开发的链接器,默认会使用多核。我还发现它比多线程运行的黄金快 2 倍 (-Wl,--threads -Wl,--thread-count,xxx)

【讨论】:

【解决方案3】:

您所指的-j 选项由make 而非gcc 处理。

使用make -j n 要求make 以多个并行进程运行Makefile 中的操作(将n 替换为数字。在make -j 2 的情况下,它是2 进程)。

在进行并行构建时,Make 可以很好地处理大多数同步任务。

【讨论】:

    【解决方案4】:

    Replacing ld with gold - any experience?,我在最低限度的综合基准上对 LD、gold 和 LLVM LLD 进行了基准测试,时间结果清楚地表明,根据 time,gold 和 LLVM LLD 都能够并行链接,例如:

    nogold:  wall=4.35s user=3.45s system=0.88s 876820kB
    gold:    wall=1.35s user=1.72s system=0.46s 739760kB
    lld:     wall=0.73s user=1.20s system=0.24s 625208kB
    

    我们知道使用并行链接是因为wall time was smaller than the user time in both of those CPUs

    这些基准还重现了 Martin Richtarsky 的 2 倍更快的 LLVM LLD 链接时间。

    【讨论】:

      【解决方案5】:

      以下是 CMake 上的两个选项(在 3.16.3 上测试):

      • 切换到gold链接器,启用多线程(设置为系统内核数):
      find_program(GNU_GOLD_PROGRAM gold)
      if (GNU_GOLD_PROGRAM)
          include(ProcessorCount)
          ProcessorCount(HOST_PROC_COUNT)
          add_link_options("-fuse-ld=gold;LINKER:--threads,--thread-count=${HOST_PROC_COUNT}")
      endif(GNU_GOLD_PROGRAM)
      
      • 切换到lld链接器(默认在多线程模式下工作):
      find_program(LLD_PROGRAM lld)
      if(LLD_PROGRAM)
          add_link_options("-fuse-ld=lld")
      endif(LLD_PROGRAM)
      

      更完整的例子:here

      【讨论】:

        猜你喜欢
        • 2011-11-06
        • 2014-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-17
        • 2023-03-16
        • 2014-03-25
        相关资源
        最近更新 更多