Czy ktoś próbował użyć gold
zamiast ld
?
gold
obiecuje być znacznie szybszy niż ld
, więc może pomóc przyspieszyć cykle testowe dla dużych aplikacji C ++, ale czy może być używany jako zamiennik ld?
Czy mogę gcc
/ g++
bezpośrednio zadzwonić gold
.?
Czy są jakieś znane błędy lub problemy?
Chociaż gold
od jakiegoś czasu jest częścią binutils GNU, w sieci nie znalazłem prawie żadnych „historii sukcesu” ani nawet „poradników”.
( Aktualizacja: dodane linki do złota i wpis na blogu wyjaśniający to )
ld
jest tak chciwa.Ponieważ zajęło mi trochę czasu, zanim dowiedziałem się, jak selektywnie używać złota (tj. Nie używać łącza symbolicznego w całym systemie), opublikuję tutaj rozwiązanie. Opiera się na http://code.google.com/p/chromium/wiki/LinuxFasterBuilds#Linking_using_gold .
~/bin/gold/
.Umieść tam następujący skrypt kleju i nazwij go
~/bin/gold/ld
:#!/bin/bash gold "$@"
Oczywiście, sprawiają, że wykonywalny
chmod a+x ~/bin/gold/ld
.Zmień swoje połączenia do
gcc
celugcc -B$HOME/bin/gold
, co czyni gcc spojrzeć w danym katalogu programów pomocniczych, jakld
i w ten sposób wykorzystuje skrypt kleju zamiast systemu defaultld
.źródło
gold
wPATH
. W przypadku łącza symbolicznego należałoby wskazać pełną ścieżkę.Aby uzupełnić odpowiedzi: istnieje opcja gcc
-fuse-ld=gold
(zobacz dokumentację gcc ). Chociaż, AFAIK, możliwe jest skonfigurowanie gcc podczas kompilacji w taki sposób, że opcja nie będzie miała żadnego efektu.źródło
-fuse-ld=gold
nie jest kompletna. Jeśli musisz użyć-Wl,-fuse-ld=gold
tego, co jest używane w czasie łącza.-Wl,
służy do przekazywania opcji bezpośrednio dold
; aby użyć innego konsolidatora, musisz o tym powiedziećgcc
. Proszę zapoznać się z dok .Jako programista Samby od kilku lat używam złotego linkera prawie wyłącznie w systemach Ubuntu, Debian i Fedora. Moja ocena:
Nie używałem złota selektywnie, ale korzystałem z linków symbolicznych lub mechanizmu alternatywnego, jeśli dystrybucja to zapewnia.
źródło
Możesz linkować
ld
dogold
(w lokalnym katalogu binarnym, jeślild
zainstalowałeś, aby uniknąć nadpisywania):ln -s `which gold` ~/bin/ld
lub
ln -s `which gold` /usr/local/bin/ld
źródło
Minimalny syntetyczny benchmark: LD vs złoto vs LLVM LLD
Wynik:
-Wl,--threads -Wl,--thread-count=$(nproc)
do włączania wielowątkowościPrzetestowano na:
sudo apt install lld
LLD 10Uproszczony opis parametrów odniesienia:
Wyniki dla różnych parametrów wzorcowych:
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
Oto skrypt, który generuje wszystkie obiekty do testów odsyłaczy:
generować obiekty
#!/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 upstream .
Zauważ, że generowanie pliku obiektowego może być dość powolne, ponieważ każdy plik C może być dość duży.
Biorąc pod uwagę dane wejściowe typu:
./generate-objects [n_int_files [n_ints_per_file [n_funcs]]]
generuje:
main.c
#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;
który prowadzi do:
relokacje na link.
Następnie porównałem:
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
Niektóre ograniczenia, które próbowałem złagodzić wybierając parametry testu:
Zauważyłem również 2x w kompilacji debugowania gem5: https://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5
Podobne pytanie: /unix/545699/what-is-the-gold-linker
Testy porównawcze Phoronix
Phoronix przeprowadził pewne testy porównawcze w 2017 r. Dla niektórych rzeczywistych projektów, ale w przypadku projektów, które badali, zyski złota nie były tak znaczące: https://www.phoronix.com/scan.php?page=article&item=lld4-linux-tests&num = 2 ( archiwum ).
Znane niezgodności
Benchmarki LLD
Na https://lld.llvm.org/ podają czasy kompilacji dla kilku dobrze znanych projektów. z wynikami podobnymi do moich syntetycznych benchmarków. Niestety nie podano wersji projektu / konsolidatora. W ich wynikach:
Komentują:
a wyniki wyglądają następująco:
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
źródło
Niektóre projekty wydają się być niekompatybilne ze złotem z powodu pewnych niekompatybilnych różnic między ld i gold. Przykład: OpenFOAM, zobacz http://www.openfoam.org/mantisbt/view.php?id=685 .
źródło
DragonFlyBSD przełączył się na złoty jako domyślny linker. Wydaje się więc, że jest gotowy na różne narzędzia.
Więcej szczegółów: http://phoronix.com/scan.php?page=news_item&px=DragonFlyBSD-Gold-Linker
źródło