用黄金代替LD-有什么经验吗?
-
28-09-2019 - |
解决方案
目前,它正在汇编Ubuntu 10.04上的较大项目。在这里,您可以轻松地将其安装和集成 binutils-gold
软件包(如果您删除了该软件包,您会得到您的旧 ld
)。 GCC然后将自动使用黄金。
一些经验:
- 黄金不搜索
/usr/local/lib
- 黄金不假定像pthread或rt这样的液体,必须手工添加它们
- 它更快,需要更少的内存(以后在具有大量增强等的大型C ++项目中很重要。)
什么不起作用:它不能编译内核内容,因此没有内核模块。如果Ubuntu更新了诸如FGLRX之类的专有驱动程序,则会通过DKMS自动执行此操作。这失败了 ld-gold
(您必须删除黄金,重新启动DKM,重新安装 ld-gold
.
其他提示
由于我花了一些时间来了解如何选择性地使用黄金(即不使用SymLink的系统范围内),我将在此处发布解决方案。它是基于 http://code.google.com/p/chromium/wiki/linuxfasterbuilds#linking_uside_gold .
- 制作一个目录,您可以在其中放一个金胶脚本。我在用
~/bin/gold/
. 将以下胶水脚本放在那里并命名
~/bin/gold/ld
:#!/bin/bash gold "$@"
显然,使其可执行,
chmod a+x ~/bin/gold/ld
.将您的电话更改为
gcc
到gcc -B$HOME/bin/gold
这使得GCC在给定目录中的助手程序中看起来像ld
因此使用胶水脚本而不是系统默认ld
.
gcc/g ++可以直接调用黄金。
只是为了补充答案:有GCC的选择 -fuse-ld=gold
(看 GCC文档)。但是,AFAIK可以在构建过程中以该选项没有任何效果的方式配置GCC。
作为Samba开发人员,我几年以来一直在Ubuntu,Debian和Fedora上使用Gold Linker。我的评估:
- 黄金比古典连接器快多次(感觉:5-10次)。
- 最初,有一些问题,但是自大约是Ubuntu 12.04以来,这已经消失了。
- 黄金链接器甚至在我们的代码中发现了一些依赖性问题,因为在某些细节方面,它似乎比经典的问题更正确。看,例如 这个桑巴人提交.
我没有选择性地使用黄金,但是如果分布提供了符号链接或替代机制。
您可以链接 ld
到 gold
(如果您有 ld
安装以避免覆盖):
ln -s `which gold` ~/bin/ld
或者
ln -s `which gold` /usr/local/bin/ld
最小的合成基准
结果:对于我尝试过的所有值,黄金的速度约为2倍至3倍。
生成对象
#!/usr/bin/env bash
set -eu
# CLI args.
# Each of those files contains n_ints_per_file ints.
n_int_file_is="${1:-10}"
n_ints_per_file="${2:-10}"
# Each function adds all ints from all files.
# This leads to n_int_file_is 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_file_is" ]; 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' '{}'"
给定类型的输入:
./generate-objects [n_int_file_is [n_ints_per_file [n_funcs]]]
这会产生一个主要的主体:
return f_0() + f_1() + ... + f_(n_funcs)()
在单独的 f_n.c
文件,并添加 n_int_file_is
时代 n_ints_per_file
外部INT:
int f_0() { return i_0_0 + i_0_1 + ... + i_(n_int_file_is)_(n_ints_per_file); }
这将导致:
n_int_file_is 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 -o main *.o
对于各种输入的三胞胎,这给出了:
10000 10 10
nogold: wall=3.70s user=2.93s system=0.75s max_mem=556356kB
gold: wall=1.43s user=1.15s system=0.28s max_mem=703060kB
1000 100 10
nogold: wall=1.23s user=1.07s system=0.16s max_mem=188152kB
gold: wall=0.60s user=0.52s system=0.07s max_mem=279108kB
100 1000 10
nogold: wall=0.96s user=0.87s system=0.08s max_mem=149636kB
gold: wall=0.53s user=0.47s system=0.05s max_mem=231596kB
10000 10 100
nogold: wall=11.63s user=10.31s system=1.25s max_mem=1411264kB
gold: wall=6.31s user=5.77s system=0.53s max_mem=2146992kB
1000 100 100
nogold: wall=7.19s user=6.56s system=0.60s max_mem=1058432kB
gold: wall=4.15s user=3.81s system=0.34s max_mem=1697796kB
100 1000 100
nogold: wall=6.15s user=5.58s system=0.57s max_mem=1031372kB
gold: wall=4.06s user=3.76s system=0.29s max_mem=1652548kB
我一直在尝试减轻一些限制:
- 在100k C文件中,两种方法偶尔会失败的mallocs
- GCC无法用1M添加来编译功能
Tested on Ubuntu 18.10, GCC 8.2.0, Lenovo ThinkPad P51 laptop, Intel Core i7-7820HQ CPU (4 cores / 8 threads), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB), Samsung MZVLB512HAJQ-000L7 SSD (3,000 MB/s )。
我还观察到GEM5的调试构建中的2倍: https://gem5.googlesource.com/public/gem5/ +/fafe4e80b76e93e93e3d0579979979904c19928587f5b5
由于LD和Gold之间存在一些不兼容的差异,有些项目似乎与黄金不相容。示例:OpenFoam,请参阅 http://www.openfoam.org/mantisbt/view.php?id=685 .
Dragonflybsd切换到黄金作为默认接头。因此,它似乎已经准备好用于各种工具。
更多细节:http://phoronix.com/scan.php?page=news_item&px=dragonflybsd-gold-linker