Quelqu'un a-t-il essayé d'utiliser gold
au lieu de ld
?
gold
promet d'être beaucoup plus rapide que ld
, donc cela peut aider à accélérer les cycles de test pour les grandes applications C++, mais peut-il être utilisé comme remplacement de remplacement pour ld?
gcc
/g++
appeler directement gold
.?
Y a-t-il des bogues ou des problèmes connus?
Bien que gold
fasse partie des binutils GNU depuis un certain temps, je n'ai trouvé quasiment aucune "success story" ni même "Howtos" sur le Web.
( Mise à jour: ajout de liens vers l'or et entrée de blog l'expliquant )
Pour le moment, il compile de plus gros projets sur Ubuntu 10.04. Ici, vous pouvez l'installer et l'intégrer facilement avec le binutils-gold
package (si vous supprimez ce package, vous obtenez votre ancien ld
). Gcc utilisera alors automatiquement l'or.
Quelques expériences:
/usr/local/lib
Ce qui ne fonctionne pas: il ne peut pas compiler de trucs de noyau et donc pas de modules de noyau. Ubuntu le fait automatiquement via DKMS s'il met à jour des pilotes propriétaires comme fglrx. Cela échoue avec ld-gold
(vous devez supprimer gold, redémarrer DKMS, réinstaller ld-gold
.
Comme il m'a fallu un peu de temps pour savoir comment utiliser sélectivement l'or (c'est-à-dire pas à l'échelle du système en utilisant un lien symbolique), je publierai la solution ici. Il est basé sur http://code.google.com/p/chromium/wiki/LinuxFasterBuilds#Linking_using_gold .
~/bin/gold/
.Mettez le script de collage suivant et nommez-le ~/bin/gold/ld
:
#!/bin/bash
gold "$@"
Évidemment, rendez-le exécutable, chmod a+x ~/bin/gold/ld
.
Modifiez vos appels en gcc
en gcc -B$HOME/bin/gold
, ce qui permet à gcc de rechercher dans le répertoire donné des programmes d'assistance comme ld
et utilise donc le script glue au lieu du système par défaut ld
.
Gcc/g ++ peut-il appeler directement l'or.?
Juste pour compléter les réponses: il y a une option gcc -Fuse-ld=gold
(voir doc gcc ). Cependant, AFAIK, il est possible de configurer gcc pendant la construction de manière à ce que l'option n'ait aucun effet.
En tant que développeur Samba, j'utilise le lieur d'or presque exclusivement sur Ubuntu, Debian et Fedora depuis plusieurs années maintenant. Mon appréciation:
Je n'ai pas utilisé l'or de manière sélective, mais j'ai utilisé des liens symboliques ou le mécanisme alternatif si la distribution le fournit.
Vous pouvez lier ld
à gold
(dans un répertoire binaire local si ld
est installé pour éviter l'écrasement):
ln -s `which gold` ~/bin/ld
ou
ln -s `which gold` /usr/local/bin/ld
Certains projets semblent incompatibles avec l'or, en raison de certaines différences incompatibles entre le ld et l'or. Exemple: OpenFOAM, voir http://www.openfoam.org/mantisbt/view.php?id=685 .
Repère synthétique minimal
Résultat: l'or était environ 2x à 3x plus rapide pour toutes les valeurs que j'ai essayées.
générer-objets
#!/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' '{}'"
Étant donné une entrée de type:
./generate-objects [n_int_file_is [n_ints_per_file [n_funcs]]]
Cela génère un principal qui fait:
return f_0() + f_1() + ... + f_(n_funcs)()
où chaque fonction est définie dans un f_n.c
fichier et ajoute n_int_file_is
fois n_ints_per_file
entrées externes:
int f_0() { return i_0_0 + i_0_1 + ... + i_(n_int_file_is)_(n_ints_per_file); }
Cela mène à:
n_int_file_is x n_ints_per_file x n_funcs
délocalisations sur le lien.
J'ai ensuite comparé:
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
pour divers triplets d'entrée, ce qui a donné:
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
Quelques limites que j'ai essayé d'atténuer:
Testé sur Ubuntu 18.10, GCC 8.2.0, ordinateur portable Lenovo ThinkPad P51, processeur Intel Core i7-7820HQ (4 cœurs/8 threads), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB), Samsung SSD MZVLB512HAJQ-000L7 (3 000 Mo/s).
J'ai également observé un 2x dans la version de débogage de gem5: https://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5
DragonFlyBSD est passé à l'or comme éditeur de liens par défaut. Il semble donc être prêt pour une variété d'outils.
Plus de détails: http://phoronix.com/scan.php?page=news_item&px=DragonFlyBSD-Gold-Linker