Alguien ha intentado utilizar oro en lugar de ld?

gold promesas a ser mucho más rápido que ld, lo que puede ayudar a acelerar los ciclos de la prueba para grandes aplicaciones de C++, pero también puede ser utilizado como sustituto para ld?

Puede gcc/g++ llamar directamente a gold.?

Hay ningún saber de los errores o problemas?

Aunque gold es parte de la GNU binutils desde hace un tiempo, he encontrado casi nada de «historias de éxito» o incluso «Tutoriales» en la Web.

(Actualización: añadidos enlaces para el oro y la entrada en el blog explicando que)

InformationsquelleAutor IanH | 2010-08-13

8 Comentarios

  1. 47

    En el momento de la compilación de los proyectos más grandes en Ubuntu 10.04. Aquí usted puede instalar e integrar fácilmente con la binutils-gold paquete (si se quita ese paquete, usted consigue su antiguo ld). Gcc automáticamente el uso del oro, a continuación,.

    Algunas experiencias:

    • de oro no buscar en /usr/local/lib
    • de oro no asume libs como pthread o rt, tenía que agregar a mano
    • es más rápido y requiere menos memoria (el posterior es importante en los grandes proyectos de C++ con una gran cantidad de boost, etc.)

    Lo que no funciona: no Se puede compilar el kernel de cosas y por lo tanto no hay módulos del kernel. Ubuntu lo hace automáticamente a través de DKMS, si se actualiza los controladores propietarios como fglrx. Esta falla con ld-gold (usted tiene que quitar de oro, reinicie DKMS, vuelva a instalar ld-gold.

    • Gracias, creo que me voy a dar una oportunidad – las restricciones que mencionas parece ser que no hay problema, en mi caso.
    • +1: gracias por compartir la experiencia. ¿Qué acerca de rendimiento ?
    • es mucho más rápido, especialmente en vinculan a los enormes bibliotecas estáticas para un binario, pero no hemos hecho ninguna de las mediciones difíciles.
    • Mis medidas eran para la vinculación de muchos de los objetos y .un archivos en un conjunto de ~30 .por lo que los archivos (uno largish, el resto pequeña) y 1 archivo ejecutable para una importante aplicación comercial. Medir el único vínculo de tiempo y ejecutando hacer en serie, tengo un tiempo total de 22.48 sec con ld vs 16.24 sec con oro, para una mejora de 6.24 segundos por construir. Sin embargo, si dejo de hacer en paralelo con 8 procesadores, la diferencia total es sólo 1.42 s por construir. El general de uso de la memoria fue un 42% de mejora, independientemente de la paralelización. YMMV.
    • muchas gracias por las cifras. El uso de la memoria de la mejora se ve muy bien, ld es tan codiciosos sobre ella.
  2. 38

    Como me tomó un poco de tiempo para averiguar cómo usar de manera selectiva de oro (es decir, no todo el sistema mediante un enlace simbólico), voy a publicar aquí la solución. Se basa en http://code.google.com/p/chromium/wiki/LinuxFasterBuilds#Linking_using_gold .

    1. Hacer un directorio donde usted puede poner un oro pegamento de secuencia de comandos. Estoy usando ~/bin/gold/.
    2. Poner el siguiente pegamento script allí y el nombre de ~/bin/gold/ld:

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

      Obviamente, hacerlo ejecutable, chmod a+x ~/bin/gold/ld.

    3. Cambiar sus llamadas a gcc a gcc -B$HOME/bin/gold que hace gcc buscar en el directorio de programas de ayuda como ld y por lo tanto utiliza el pegamento de la secuencia de comandos en lugar de el sistema por defecto ld.

    • Que es necesario para que el sistema operativo? Como nob dijo en su respuesta, para Ubuntu solo tienes que instalar el oro binutils-el paquete y el compilador utilizará el inmediato. Mismo para openSuse.
    • Sí, es muy fácil de reemplazar ld de todo el sistema. Mi respuesta fue orientadas particularmente a cómo utilizar el oro de forma selectiva. Y en ese caso, creo que, es necesario para cualquier sistema operativo.
    • Sólo podía hacer un enlace en lugar de un guión envoltorio…
    • Sí, la ventaja de la secuencia de comandos es que parece que para gold en el PATH. Para un enlace simbólico, tendría que apuntar a la ruta de acceso completa.
    • ah, cierto que
  3. 12

    Puede gcc/g++ llamar directamente de oro.?

    Sólo para complementar las respuestas: hay una gcc opción -fuse-ld=gold (ver gcc doc). Aunque, AFAIK, es posible configurar gcc durante el construir de una manera que la opción no tendrá ningún efecto.

    • -fuse-ld=gold no es completa. Si usted tiene que utilizar -Wl,-fuse-ld=gold como se utiliza en el enlace de tiempo.
  4. 9

    Como una Samba desarrollador, he estado usando el oro enlazador casi exclusivamente en Ubuntu, Debian y Fedora desde hace ya varios años. Mi valoración:

    • de oro es que muchas veces (sentido: de 5 a 10 veces) más rápido que el clásico enlazador.
    • Inicialmente, hubo un par de problemas, pero la han ido desde aproximadamente Ubuntu 12.04.
    • El oro enlazador incluso encontrar algunos de los problemas de dependencia en nuestro código, ya que parece ser más correcto que el clásico con respecto a algunos detalles. Ver, por ejemplo,esta Samba cometer.

    No he utilizado el oro de forma selectiva, pero que han sido el uso de enlaces simbólicos o las alternativas mecanismo, si la distribución se la proporciona.

  5. 8

    Puede vincular ld a gold (en un local de directorio de binarios si usted tiene ld instalado para evitar la sobreescritura):

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

    o

    ln -s `which gold` /usr/local/bin/ld
  6. 3

    Mínimo sintético referencia

    Resultado: medalla de oro fue acerca de 2x a 3x más rápido para todos los valores que he probado.

    generar objetos

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

    Dado una entrada del tipo:

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

    Esto genera un principal que hace:

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

    donde cada función está definida en un aparte f_n.c archivo, y añade n_int_file_is veces n_ints_per_file extern int:

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

    Esto conduce a:

    n_int_file_is x n_ints_per_file x n_funcs

    traslados en el enlace.

    Luego he comparado:

    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

    para la entrada de varios tripletes, que dio:

    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

    Algunos de los límites que he estado tratando de mitigar:

    • a 100k C archivos, ambos métodos obtienen error mallocs ocasionalmente
    • GCC no se puede compilar una función con 1 m de adiciones

    Probado en Ubuntu 18.10, GCC 8.2.0, Lenovo ThinkPad P51 portátil, Intel Core i7-7820HQ de la CPU (4 núcleos /8 hilos), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB), Samsung MZVLB512HAJQ-000L7 SSD (3.000 MB/s).

    También he observado un 2x en la generación de depuración de gem5: https://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5

Dejar respuesta

Please enter your comment!
Please enter your name here