Hat jemand versucht, gold
anstelle von ld
zu verwenden?
gold
verspricht viel schneller als ld
zu sein, daher kann es helfen, die Testzyklen für große C++ - Anwendungen zu beschleunigen, kann aber als Ersatz für verwendet werden ld?
Kann gcc
/g++
direkt gold
aufrufen.?
Gibt es bekannte Fehler oder Probleme?
Obwohl gold
seit einiger Zeit Teil der GNU binutils ist, habe ich im Web fast keine "Erfolgsgeschichten" oder gar "Howtos" gefunden.
( Update: Links zu Gold und Blog-Eintrag hinzugefügt, um es zu erklären )
Momentan werden größere Projekte auf Ubuntu 10.04 kompiliert. Hier können Sie es einfach mit dem Paket binutils-gold
Installieren und integrieren (wenn Sie dieses Paket entfernen, erhalten Sie Ihr altes ld
). Gcc verwendet dann automatisch Gold.
Einige Erfahrungen:
/usr/local/lib
Was nicht funktioniert: Es kann kein Kernel-Material und daher keine Kernel-Module kompilieren. Ubuntu macht dies automatisch über DKMS, wenn proprietäre Treiber wie fglrx aktualisiert werden. Dies schlägt mit ld-gold
Fehl (Sie müssen Gold entfernen, DKMS neu starten, ld-gold
Neu installieren).
Da ich eine Weile gebraucht habe, um herauszufinden, wie man Gold selektiv verwendet (d. H. Nicht systemweit mithilfe eines Symlinks), werde ich die Lösung hier veröffentlichen. Es basiert auf http://code.google.com/p/chromium/wiki/LinuxFasterBuilds#Linking_using_gold .
~/bin/gold/
.Gib das folgende Klebeskript ein und nenne es ~/bin/gold/ld
:
#!/bin/bash
gold "[email protected]"
Machen Sie es natürlich ausführbar, chmod a+x ~/bin/gold/ld
.
Ändern Sie Ihre Anrufe in gcc
in gcc -B$HOME/bin/gold
, wodurch gcc im angegebenen Verzeichnis nach Hilfsprogrammen wie ld
sucht und daher das Glue-Skript anstelle des System-Standards ld
verwendet.
Kann gcc/g ++ direkt Gold aufrufen?
Nur um die Antworten zu ergänzen: es gibt eine gcc-Option -Fuse-ld=gold
(siehe gcc doc ). AFAIK, es ist jedoch möglich, gcc während des Builds so zu konfigurieren, dass die Option keine Auswirkungen hat.
Als Samba-Entwickler benutze ich den Gold-Linker seit einigen Jahren fast ausschließlich auf Ubuntu, Debian und Fedora. Meine Einschätzung:
Ich habe Gold nicht selektiv verwendet, sondern Symlinks oder den alternativen Mechanismus verwendet, sofern die Distribution dies vorsieht.
Sie können ld
mit gold
verknüpfen (in einem lokalen Binärverzeichnis, wenn Sie ld
installiert haben, um ein Überschreiben zu vermeiden):
ln -s `which gold` ~/bin/ld
oder
ln -s `which gold` /usr/local/bin/ld
Einige Projekte scheinen mit Gold nicht kompatibel zu sein, da es einige inkompatible Unterschiede zwischen ld und Gold gibt. Beispiel: OpenFOAM, siehe http://www.openfoam.org/mantisbt/view.php?id=685 .
Minimaler synthetischer Benchmark
Ergebnis: Gold war bei allen Werten, die ich ausprobiert habe, etwa 2x bis 3x schneller.
objekte erzeugen
#!/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' '{}'"
Bei einer Eingabe vom Typ:
./generate-objects [n_int_file_is [n_ints_per_file [n_funcs]]]
Dies erzeugt eine Hauptleitung, die Folgendes bewirkt:
return f_0() + f_1() + ... + f_(n_funcs)()
wobei jede Funktion in einer separaten f_n.c
- Datei definiert ist und n_int_file_is
mal n_ints_per_file
externe Ints hinzufügt:
int f_0() { return i_0_0 + i_0_1 + ... + i_(n_int_file_is)_(n_ints_per_file); }
Dies führt zu:
n_int_file_is x n_ints_per_file x n_funcs
mzüge auf dem Link.
Dann habe ich verglichen:
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
für verschiedene Eingangsdrillinge, die ergaben:
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
Einige Grenzen habe ich versucht zu mildern:
Getestet auf Ubuntu 18.10, GCC 8.2.0, Lenovo ThinkPad P51, Intel Core i7-7820HQ-CPU (4 Kerne/8 Threads), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB), Samsung MZVLB512HAJQ-000L7 SSD (3.000 MB/s).
Ich habe auch ein 2x im Debugbuild von gem5 beobachtet: https://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5
DragonFlyBSD hat als Standardlinker auf Gold umgestellt. Es scheint also für eine Vielzahl von Werkzeugen bereit zu sein.
Weitere Details: http://phoronix.com/scan.php?page=news_item&px=DragonFlyBSD-Gold-Linker