Ld vervangen door goud – enige ervaring?

Heeft iemand geprobeerd om in plaats daarvan goldte gebruiken van ld?

goldbelooftveel sneller te zijn dan ld, dus het kan helpen bij het versnellen van testcycli voor grote C++-toepassingen, maar kan het worden gebruikt als vervanging voor ld?

Kan gcc/g++rechtstreeks goldbellen.?

Zijn er bekende bugs of problemen?

Hoewel goldal een tijdje deel uitmaakt van de GNU binutils, heb ik bijna geen “succesverhalen” of zelfs “Howto’s” op het web gevonden.

(Update: links naar goud toegevoegd en blogbericht met uitleg)


Antwoord 1, autoriteit 100%

Op dit moment compileert het grotere projecten op Ubuntu 10.04. Hier kunt u het eenvoudig installeren en integreren met het binutils-goldpakket (als u dat pakket verwijdert, krijgt u uw oude ld). Gcc gebruikt dan automatisch goud.

Enkele ervaringen:

  • goud zoekt niet in /usr/local/lib
  • gold neemt geen libs zoals pthread of rt aan, moest ze met de hand toevoegen
  • het is sneller en heeft minder geheugen nodig (het laatste is belangrijk bij grote C++-projecten met veel boost enz.)

Wat niet werkt: Het kan geen kernel-dingen compileren en daarom geen kernelmodules. Ubuntu doet dit automatisch via DKMS als het eigen stuurprogramma’s zoals fglrx bijwerkt. Dit mislukt met ld-gold(je moet goud verwijderen, DKMS opnieuw opstarten, ld-goldopnieuw installeren.


Antwoord 2, autoriteit 80%

Omdat het even duurde voordat ik erachter kwam hoe ik selectief goud kon gebruiken (d.w.z. niet voor het hele systeem met een symbolische link), zal ik de oplossing hier posten. Het is gebaseerd op http://code.google.com/p/chromium/wiki/ LinuxFasterBuilds#Linking_using_gold.

  1. Maak een map waarin je een goudlijmscript kunt plaatsen. Ik gebruik ~/bin/gold/.
  2. Plaats het volgende lijmscript daar en noem het ~/bin/gold/ld:

    #!/bin/bash
    gold "[email protected]"
    

    Uiteraard, maak het uitvoerbaar, chmod a+x ~/bin/gold/ld.

  3. Wijzig uw oproepen naar gccnaar gcc -B$HOME/bin/goldwaardoor gcc in de opgegeven directory zoekt naar hulpprogramma’s zoals lden gebruikt dus het lijmscript in plaats van de systeemstandaard ld.


Antwoord 3, autoriteit 37%

Kan gcc/g++ rechtstreeks goud noemen.?

Om de antwoorden aan te vullen: er is een gcc-optie -fuse-ld=gold(zie gcc-document). AFAIK, het is echter mogelijk om gcc tijdens het bouwen zo te configureren dat de optie geen effect heeft.


Antwoord 4, autoriteit 22%

Minimale synthetische benchmark: LD versus goud versus LLVM LLD

Resultaat:

  • goudwas ongeveer 3x tot 4x sneller voor alle waarden die ik heb geprobeerd bij het gebruik van -Wl,--threads -Wl,--thread-count=$(nproc)om multithreading in te schakelen
  • LLDwas ongeveer 2x sneller dan goud!

Getest op:

  • Ubuntu 20.04, GCC 9.3.0, binutils 2.34, sudo apt install lldLLD 10
  • 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).

Vereenvoudigde beschrijving van de benchmarkparameters:

  • 1: aantal objectbestanden met symbolen
  • 2: aantal symbolen per symboolprovider-objectbestand
  • 3: aantal objectbestanden waarin alle geleverde symbolensymbolen worden gebruikt

Resultaten voor verschillende benchmarkparameters:

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

Dit is het script dat alle objecten voor de linktests genereert:

objecten genereren

#!/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 stroomopwaarts.

Merk op dat het genereren van objectbestanden vrij traag kan zijn, aangezien elk C-bestand behoorlijk groot kan zijn.

Gegeven een type invoer:

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

het genereert:

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;

wat leidt tot:

n_int_files x n_ints_per_file x n_funcs

verhuizingenop de link.

Toen vergeleek ik:

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

Sommige limieten die ik heb proberen te verminderen bij het selecteren van de testparameters:

  • bij 100k C-bestanden krijgen beide methoden af ​​en toe mislukte mallocs
  • GCC kan geen functie compileren met 1 miljoen toevoegingen

Ik heb ook een 2x waargenomen in de debug-build van gem5: https:// gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5

Vergelijkbare vraag: https://unix.stackexchange.com/questions/545699/ wat-is-de-gouden-linker

Phoronix-benchmarks

Phoronix deed in 2017 wat benchmarking voor een aantal echte projecten, maar voor de projecten die ze onderzochten, waren de goudwinsten niet zo significant: https://www.phoronix.com/scan.php?page=article&item=lld4-linux-tests&num= 2(archief).

Bekende onverenigbaarheden

LLD-benchmarks

Bij https://lld.llvm.org/geven ze bouwtijden voor een paar bekende projecten. met vergelijkbare resultaten als mijn synthetische benchmarks. Project/linker versies worden helaas niet gegeven. In hun resultaten:

  • Goud was ongeveer 3x/4x sneller dan LD
  • LLD was 3x/4x sneller dan goud, dus een grotere versnelling dan in mijn synthetische benchmark

Ze reageren:

Dit is een linktijdvergelijking op een 2-socket 20-core 40-thread Xeon E5-2680 2,80 GHz-machine met een SSD-schijf. We hebben goud en lld uitgevoerd met of zonder ondersteuning voor multi-threading. Om multi-threading uit te schakelen, hebben we -no-threads toegevoegd aan de opdrachtregels.

en resultaten zien er als volgt uit:

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

Antwoord 5, autoriteit 20%

Als Samba-ontwikkelaar gebruik ik de gouden linker sinds enkele jaren bijna uitsluitend op Ubuntu, Debian en Fedora. Mijn beoordeling:

  • Goud is vele malen (voelt: 5-10 keer) sneller dan de klassieke linker.
  • Aanvankelijk waren er een paar problemen, maar die zijn sinds ongeveer Ubuntu 12.04 verdwenen.
  • De gouden linker heeft zelfs enkele afhankelijkheidsproblemen in onze code gevonden, omdat deze met betrekking tot enkele details correcter lijkt te zijn dan de klassieke. Zie bijv. deze Samba-toezegging.

Ik heb goud niet selectief gebruikt, maar ik heb symbolische links of het alternatieve mechanisme gebruikt als de distributie dit biedt.


Antwoord 6, autoriteit 17%

Je zou ldkunnen linken aan gold(in een lokale binaire map als je ldhebt geïnstalleerd om overschrijven te voorkomen):

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

of

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

Antwoord 7, autoriteit 6%

Sommige projecten lijken onverenigbaar met goud, vanwege enkele onverenigbare verschillen tussen ld en goud. Voorbeeld: OpenFOAM, zie http://www.openfoam.org/mantisbt/view. php?id=685.


Antwoord 8, autoriteit 4%

DragonFlyBSD schakelde over op goud als hun standaard linker. Het lijkt dus klaar te zijn voor een verscheidenheid aan tools.
Meer details:
http://phoronix.com/scan.php?page=news_item&amp ;px=DragonFlyBSD-Gold-Linker

Other episodes