用黄金替换 ld - 有经验吗?

新手上路,请多包涵

有没有人尝试使用 gold 而不是 ld

gold 承诺ld 快得多,因此它可能有助于加快大型 C++ 应用程序的测试周期,但它可以用作 ld 的替代品吗?

可以 gcc / g++ 直接调用 gold .?

是否有任何已知的错误或问题?

虽然 gold 是 GNU binutils 的一部分,但我在 Web 上几乎找不到“成功案例”甚至“Howtos”。

( _更新:添加了指向黄金的链接和解释它的博客条目_)

原文由 IanH 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

目前它正在 Ubuntu 10.04 上编译更大的项目。在这里,您可以轻松地安装它并将其与 binutils-gold 软件包集成(如果删除该软件包,您将得到旧的 ld )。 Gcc 将自动使用黄金。

一些经验:

  • 黄金不在 /usr/local/lib
  • gold 不假设像 pthread 或 rt 这样的库,必须手动添加它们
  • 它更快并且需要更少的内存(后者在具有大量提升等的大型 C++ 项目中很重要)

什么不起作用:它不能编译内核的东西,因此没有内核模块。如果 Ubuntu 更新了 fglrx 等专有驱动程序,它会通过 DKMS 自动执行此操作。这失败了 ld-gold (你必须删除黄金,重新启动 DKMS,重新安装 ld-gold

原文由 nob 发布,翻译遵循 CC BY-SA 3.0 许可协议

最小综合基准:LD vs Gold vs LLVM LLD

结果:

  • 使用 -Wl,--threads -Wl,--thread-count=$(nproc) 启用多线程时,我尝试过的所有值的 gold 大约快 3 到 4 倍
  • LLD 比黄金快 2 倍!

测试:

  • Ubuntu 20.04、GCC 9.3.0、binutils 2.34、 sudo apt install lld LLD 10
  • Lenovo ThinkPad P51 笔记本电脑,Intel Core i7-7820HQ CPU(4 核 / 8 线程),2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB),Samsung MZVLB512HAJQ-000L7 SSD (3,000 MB/s)。

基准参数的简化说明:

  • 1:提供符号的目标文件数
  • 2:每个符号提供程序对象文件的符号数
  • 3:使用所有提供的符号符号的目标文件数

不同基准参数的结果:

 10000 10 10
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

1000 100 10
nogold:  wall=5.08s user=4.17s system=0.89s 924040kB
gold:    wall=1.57s user=2.18s system=0.54s 922712kB
lld:     wall=0.75s user=1.28s system=0.27s 664804kB

100 1000 10
nogold:  wall=5.53s user=4.53s system=0.95s 962440kB
gold:    wall=1.65s user=2.39s system=0.61s 987148kB
lld:     wall=0.75s user=1.30s system=0.25s 704820kB

10000 10 100
nogold:  wall=11.45s user=10.14s system=1.28s 1735224kB
gold:    wall=4.88s user=8.21s system=0.95s 2180432kB
lld:     wall=2.41s user=5.58s system=0.74s 2308672kB

1000 100 100
nogold:  wall=13.58s user=12.01s system=1.54s 1767832kB
gold:    wall=5.17s user=8.55s system=1.05s 2333432kB
lld:     wall=2.79s user=6.01s system=0.85s 2347664kB

100 1000 100
nogold:  wall=13.31s user=11.64s system=1.62s 1799664kB
gold:    wall=5.22s user=8.62s system=1.03s 2393516kB
lld:     wall=3.11s user=6.26s system=0.66s 2386392kB

这是为链接测试生成所有对象的脚本:

生成对象

#!/usr/bin/env bash
set -eu

# CLI args.

# Each of those files contains n_ints_per_file ints.
n_int_files="${1:-10}"
n_ints_per_file="${2:-10}"

# Each function adds all ints from all files.
# This leads to n_int_files x n_ints_per_file x n_funcs relocations.
n_funcs="${3:-10}"

# Do a debug build, since it is for debug builds that link time matters the most,
# as the user will be recompiling often.
cflags='-ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic'

# Cleanup previous generated files objects.
./clean

# Generate i_*.c, ints.h and int_sum.h
rm -f ints.h
echo 'return' > int_sum.h
int_file_i=0
while [ "$int_file_i" -lt "$n_int_files" ]; do
  int_i=0
  int_file="${int_file_i}.c"
  rm -f "$int_file"
  while [ "$int_i" -lt "$n_ints_per_file" ]; do
    echo "${int_file_i} ${int_i}"
    int_sym="i_${int_file_i}_${int_i}"
    echo "unsigned int ${int_sym} = ${int_file_i};" >> "$int_file"
    echo "extern unsigned int ${int_sym};" >> ints.h
    echo "${int_sym} +" >> int_sum.h
    int_i=$((int_i + 1))
  done
  int_file_i=$((int_file_i + 1))
done
echo '1;' >> int_sum.h

# Generate funcs.h and main.c.
rm -f funcs.h
cat <<EOF >main.c
#include "funcs.h"

int main(void) {
return
EOF
i=0
while [ "$i" -lt "$n_funcs" ]; do
  func_sym="f_${i}"
  echo "${func_sym}() +" >> main.c
  echo "int ${func_sym}(void);" >> funcs.h
  cat <<EOF >"${func_sym}.c"
#include "ints.h"

int ${func_sym}(void) {
#include "int_sum.h"
}
EOF
  i=$((i + 1))
done
cat <<EOF >>main.c
1;
}
EOF

# Generate *.o
ls | grep -E '\.c$' | parallel --halt now,fail=1 -t --will-cite "gcc $cflags -c -o '{.}.o' '{}'"

GitHub 上游.

请注意,目标文件的生成可能非常缓慢,因为每个 C 文件都可能非常大。

给定一个类型的输入:

 ./generate-objects [n_int_files [n_ints_per_file [n_funcs]]]

它生成:

主程序

#include "funcs.h"

int main(void) {
    return f_0() + f_1() + ... + f_<n_funcs>();
}

f_0.c , f_1.c , …, f_<n_funcs>.c

 extern unsigned int i_0_0;
extern unsigned int i_0_1;
...
extern unsigned int i_1_0;
extern unsigned int i_1_1;
...
extern unsigned int i_<n_int_files>_<n_ints_per_file>;

int f_0(void) {
    return
    i_0_0 +
    i_0_1 +
    ...
    i_1_0 +
    i_1_1 +
    ...
    i_<n_int_files>_<n_ints_per_file>
}

0.c , 1.c , …, <n_int_files>.c

 unsigned int i_0_0 = 0;
unsigned int i_0_1 = 0;
...
unsigned int i_0_<n_ints_per_file> = 0;

这导致:

 n_int_files x n_ints_per_file x n_funcs

链接上的 重定位

然后我比较了:

 gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic               -o main *.o
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -fuse-ld=gold -Wl,--threads -Wl,--thread-count=`nproc` -o main *.o
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -fuse-ld=lld  -o main *.o

在选择测试参数时,我一直试图减轻一些限制:

  • 在 100k C 文件中,这两种方法偶尔都会出现失败的 malloc
  • GCC 无法编译添加 1M 的函数

我还在 gem5 的调试版本中观察到了 2 倍: https ://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5

类似的问题: https ://unix.stackexchange.com/questions/545699/what-is-the-gold-linker

Phoronix 基准测试

Phoronix 在 2017 年对一些现实世界的项目进行了一些基准测试,但对于他们检查的项目,黄金收益并不那么显着: https ://www.phoronix.com/scan.php?page=article&item=lld4-linux-tests&num =2存档)。

已知的不兼容性

LLD 基准

https://lld.llvm.org/ ,他们给出了一些知名项目的构建时间。结果与我的综合基准相似。不幸的是,没有给出项目/链接器版本。在他们的结果中:

  • 黄金比 LD 快大约 3 倍/4 倍
  • LLD 比黄金快 3 倍/4 倍,因此比我的综合基准测试更快

他们评论说:

这是具有 SSD 驱动器的 2 插槽 20 核 40 线程 Xeon E5-2680 2.80 GHz 机器上的链接时间比较。我们在有或没有多线程支持的情况下运行 gold 和 lld。为了禁用多线程,我们在命令行中添加了 -no-threads。

结果如下:

 Program      | Size     | GNU ld  | gold -j1 | gold    | lld -j1 |    lld
-------------|----------|---------|----------|---------|---------|-------
  ffmpeg dbg |   92 MiB |   1.72s |   1.16s  |   1.01s |   0.60s |  0.35s
  mysqld dbg |  154 MiB |   8.50s |   2.96s  |   2.68s |   1.06s |  0.68s
   clang dbg | 1.67 GiB | 104.03s |  34.18s  |  23.49s |  14.82s |  5.28s
chromium dbg | 1.14 GiB | 209.05s |  64.70s  |  60.82s |  27.60s | 16.70s

原文由 Ciro Santilli OurBigBook.com 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏