链接时gcc可以使用多个内核吗?

Posted

技术标签:

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

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

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

【问题讨论】:

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

【讨论】:

我使用***.com/a/64128746/895245 中描述的精确基准来复制 LLD 比黄金快 2 倍【参考方案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

【讨论】:

以上是关于链接时gcc可以使用多个内核吗?的主要内容,如果未能解决你的问题,请参考以下文章

遵循简单的内核教程时奇怪的链接器错误gcc

gcc默认链接到libc.a或libc.so吗?

怎样用gcc或者ld链接.dll文件

让 GCC 链接器警告多个函数定义

gcc升级后静态库要升级吗

如何在 AIX 中使用 GCC 编译器链接 *.so 文件