Domanda

Qualcuno ha cercato di utilizzare gold invece di ld?

gold href="http://www.airs.com/blog/archives/38" rel="noreferrer"> promesse di essere molto più veloce di ld, quindi potrebbe contribuire ad accelerare prova cicli per grandi applicazioni C ++, ma può essere usato come rimpiazzo per ld?

Può gcc / g++ gold direttamente chiamata.?

Ci sono insetti conoscere o problemi?

Anche se gold fa parte delle binutils GNU da un po ', ho trovato quasi nessuna "storie di successo" o anche "Howto" nel Web.

( Aggiornamento: collegamenti a oro e blog che spiegano ha aggiunto )

È stato utile?

Soluzione

Al momento di compilare più grandi progetti su Ubuntu 10.04. Qui è possibile installare e integrarlo facilmente con il pacchetto binutils-gold (se si rimuove quel pacchetto, si ottiene il vecchio ld). Gcc utilizzerà automaticamente l'oro poi.

Alcune esperienze:

  • oro non cerca nei /usr/local/lib
  • l'oro non si assume librerie come pthread o rt, ha dovuto aggiungerli a mano
  • è più veloce e ha bisogno di meno memoria (il secondo è importante sul grande C ++ progetti con un sacco di spinta, ecc.)

Quello che non funziona: non può compilazione roba kernel e quindi non i moduli del kernel. Ubuntu fa automaticamente tramite DKMS se aggiorna i driver proprietari come fglrx. Questo viene a mancare con ld-gold (è necessario rimuovere l'oro, DKMS riavvio, reinstallare ld-gold.

Altri suggerimenti

Per quanto mi c'è voluto un po 'per scoprire come utilizzare in modo selettivo l'oro (vale a dire non a livello di sistema usando un link simbolico), vi posterò la soluzione qui. Si basa su http://code.google.com/p/chromium/wiki/ LinuxFasterBuilds # Linking_using_gold .

  1. Creare una directory dove si può mettere uno script di colla d'oro. Sto usando ~/bin/gold/.
  2. Inserire il seguente script colla lì e il nome ~/bin/gold/ld:

    #!/bin/bash
    gold "$@"
    

    Ovviamente, renderlo eseguibile, chmod a+x ~/bin/gold/ld.

  3. Cambia le chiamate a gcc a gcc -B$HOME/bin/gold che rende sguardo gcc nella directory data per i programmi di supporto come ld e quindi utilizza lo script colla al posto del ld sistema di default.

  

Può gcc / g ++ oro direttamente chiamata.?

Proprio per integrare le risposte: non c'è possibilità di un -fuse-ld=gold gcc (vedi gcc doc ). Anche se, per quanto ne so, è possibile configurare gcc durante la costruzione, in modo che l'opzione non avrà alcun effetto.

Come sviluppatore Samba, ho utilizzato il linker oro quasi esclusivamente su Ubuntu, Debian, Fedora e da diversi anni a questa parte. La mia valutazione:

  • l'oro è molte volte (sentita: 5-10 volte). Più veloce del linker classica
  • Inizialmente, ci sono stati alcuni problemi, ma l'essere andato dal grosso modo Ubuntu 12.04.
  • Il linker oro anche trovato alcuni problemi con le dipendenze nel nostro codice, dal momento che sembra essere più corretta rispetto a quella classica per quanto riguarda alcuni dettagli. Vedi, ad esempio, questa Samba commettere .

non ho usato oro selettivamente, ma sono stati utilizzando link simbolici o meccanismi alternativi se la distribuzione fornisce.

Si potrebbe creare un collegamento a ld gold (in una directory locali binari se si è ld installato per evitare di sovrascrivere):

ln -s `which gold` ~/bin/ld

o

ln -s `which gold` /usr/local/bin/ld

benchmark sintetico Minimal

Risultato: l'oro era di circa 2x a 3 volte più veloce per tutti i valori che ho provato

.

Genera-oggetti

#!/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' '{}'"

GitHub monte .

Dato un ingresso di tipo:

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

Questo genera una principale che fa:

return f_0() + f_1() + ... + f_(n_funcs)()

dove ogni funzione è definita in un file f_n.c separata, e aggiunge volte n_int_file_is n_ints_per_file int Esterno:

int f_0() { return i_0_0 + i_0_1 + ... + i_(n_int_file_is)_(n_ints_per_file); }

Questo porta a:

n_int_file_is x n_ints_per_file x n_funcs

delocalizzazioni sul link.

Poi ho confrontato:

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

per varie triplette di ingresso, che ha dato:

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

Alcuni limiti ho cercato di mitigare:

  • mallocs a 100k file C, entrambi i metodi vengono di tanto in tanto hanno fallito
  • GCC non può compilare una funzione con aggiunte 1M

testato su Ubuntu 18.10, GCC 8.2.0, Lenovo ThinkPad laptop P51, Intel Core i7-7820HQ CPU (4 core / 8 thread), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB), Samsung MZVLB512HAJQ-000L7 SSD (3.000 MB / s).

Ho anche osservato una 2x nella build di debug di gem5: https: // gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5

Alcuni progetti sembrano essere incompatibili con l'oro, a causa di alcune differenze incompatibili tra ld e oro. Esempio: OpenFOAM, vedi http://www.openfoam.org/mantisbt/view. php? id = 685 .

DragonFlyBSD passa ad oro come loro linker di default. Così sembra essere pronto per una varietà di strumenti.
Più dettagli: http://phoronix.com/scan.php?page=news_item&px=DragonFlyBSD -Gold-Linker

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top