source

ld를 골드로 대체 - 경험 있습니까?

goodcode 2022. 8. 12. 23:21
반응형

ld를 골드로 대체 - 경험 있습니까?

다른 사람이 대신 사용하려고 한 적이 있습니까?ld

gold 보다 훨씬 빠를 것 같다ld따라서 대규모 C++ 어플리케이션의 테스트 사이클을 고속화하는 데 도움이 될 수 있지만 ld의 드롭인 대체로 사용할 수 있습니까?

수 있다gcc/g++ 전화를 걸다gold

알고 있는 버그나 문제가 있습니까?

일일 ~일도 although although although although 。gold한동안 GNU의 일부이기도 하지만 웹에서 '성공 사례'나 '하우토스'조차 거의 찾을 수 없었습니다.

(갱신: 골드 링크 및 블로그 엔트리에 대한 설명 추가)

최소 합성 벤치마크: LD vs 골드 vs LLD

결과:

  • Gold는 지금까지 사용해 본 값보다 3~4배 더 빠릅니다.-Wl,--threads -Wl,--thread-count=$(nproc)을 유효하게
  • LLD는 금보다 약 2배 빨랐어요!

테스트 대상:

  • Ubuntu 20.04, GCC 9.3.0, binutils 2.34,sudo apt install lld 10LD 10
  • Lenovo ThinkPad P51 노트북, 인텔 Core i7-7820HQ CPU (4코어/8스레드), 삼성 M471A2K43BB1-CRC RAM (2x16GiB), 삼성 MZVLB512HAJQ-000L7 SSD (3,000 MB/s)

벤치마크 파라미터의 간단한 설명:

  • 1: 기호를 제공하는 객체 파일의 수
  • 2: 기호 공급자 개체 파일당 기호 수
  • 3: 제공된 모든 기호를 사용한 객체 파일 수

다양한 벤치마크 파라미터에 대한 결과:

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

링크 테스트의 모든 개체를 생성하는 스크립트는 다음과 같습니다.

생성-유효과의

#!/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 업스트림

각 C 파일은 매우 클 수 있기 때문에 오브젝트 파일의 생성은 매우 느릴 수 있습니다.

입력된 유형:

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

다음을 생성합니다.

메인

#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;

그 결과 다음과 같습니다.

n_int_files x n_ints_per_file x n_funcs

링크상의 재배치.

그리고 비교했습니다.

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

테스트 파라미터를 선택할 때 몇 가지 제한을 완화하려고 했습니다.

  • 100k C 파일에서는 두 방법 모두 malloc에 실패할 수 있습니다.
  • GCC는 함수를 1M 추가 기능으로 컴파일할 수 없습니다.

gem5의 디버깅빌드에서 2x가 검출되었습니다.https://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5

유사한 질문: https://unix.stackexchange.com/questions/545699/what-is-the-gold-linker

Phoronix 벤치마크

Phoronix는 2017년에 일부 실제 프로젝트의 벤치마킹을 실시했지만, 그들이 조사한 프로젝트의 경우, 금의 이익은 그다지 크지 않았다: https://www.phoronix.com/scan.php?page=article&item=lld4-linux-tests&num=2 (2010년.

기존의 비호환성

  • 골드
    • LD와 부분 링크를 한 후 골드로 마지막 링크를 시도하면 https://sourceware.org/bugzilla/show_bug.cgi?id=23869 gold가 실패했습니다.lld는 같은 테스트 케이스에서 일했다.
    • https://github.com/cirosantilli/linux-kernel-module-cheat/issues/109 디버깅 기호가 파손되어 있는 곳이 있습니다.

LLD 벤치마크

https://lld.llvm.org/에서는 몇 가지 잘 알려진 프로젝트에 대해 빌드 시간을 제공합니다.제 종합 벤치마크와 비슷한 결과를 얻었습니다.프로젝트/링커 버전은 아쉽게도 제공되지 않습니다.그 결과:

  • 금은 LD보다 약 3/4배 빨랐다.
  • LLD는 골드보다 3/4배 빨랐기 때문에 합성 벤치마크보다 고속화

코멘트:

SSD 드라이브를 탑재한 2 소켓20 코어 40 스레드 Xeon E5-2680 2.80 GHz 머신에서의 링크 시간 비교입니다.멀티 스레드 지원 유무에 관계없이 Gold와 Lld를 실행했습니다.멀티스레딩을 비활성화하기 위해 명령줄에 -no-threads를 추가했습니다.

결과는 다음과 같습니다.

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

symblink를 사용하여 시스템 전체를 사용하지 않고 골드를 선택적으로 사용하는 방법을 찾는 데 시간이 걸렸으므로 여기에 솔루션을 게시합니다.http://code.google.com/p/chromium/wiki/LinuxFasterBuilds#Linking_using_gold에 근거하고 있습니다.

  1. 골드 글루 스크립트를 넣을 수 있는 디렉토리를 만듭니다.하고 .~/bin/gold/.
  2. 를 붙이고 .~/bin/gold/ld:

    #!/bin/bash
    gold "$@"
    

    실행한 것으로 .chmod a+x ~/bin/gold/ld.

  3. 을 「」로 변경합니다.gcc로로 합니다.gcc -B$HOME/bin/gold 된 디렉토리에서 gcc의 .ld system-default gludefault 합니다.ld.

gcc/g++는 직접 Gold를 호출할 수 있습니까?

: 인 gcc가 .-fuse-ld=gold(gcc doc 참조).다만, AFAIK 에서는, 빌드중에 옵션을 유효하게 하지 않는 방법으로 gcc 를 설정할 수 있습니다.

우분투 10.04입니다.을 쉽게 할 수 .binutils-gold가 표시됩니다.ld GCC를 사용하다

몇 가지 경험:

  • 되지 않는다/usr/local/lib
  • 금은 pthread나 rt와 같은 libs를 가정하지 않고 손으로 추가해야 했다.
  • 고속으로 필요한 메모리도 적습니다(후자가 큰 C++ 프로젝트 등에서는 중요).

기능하지 않는 점:커널을 컴파일할 수 없기 때문에 커널 모듈이 없습니다.Ubuntu는 fglrx와 같은 자체 드라이버를 업데이트하면 DKMS를 통해 자동으로 이 작업을 수행합니다.이것은 에서 실패합니다.ld-gold(골드를 제거하고 DKMS를 재시작하여 재설치해야 합니다.ld-gold.

Samba 개발자로서 저는 몇 년 전부터 Ubuntu, Debian, Fedora에서 골드링커를 거의 독점적으로 사용하고 있습니다.제 평가:

  • 골드는 기존 링커보다 몇 배(느낌: 5~10배) 빠릅니다.
  • 처음에는 몇 가지 문제가 있었지만 대략 Ubuntu 12.04 이후로는 문제가 발생하지 않았습니다.
  • Gold Linker는 심지어 우리의 코드에서 일부 종속성 문제를 발견했는데, 이는 일부 세부 사항에 관해서는 기존의 코드보다 더 정확한 것처럼 보이기 때문입니다.를 들어 이 Samba 커밋을 참조하십시오.

골드를 선별적으로 사용한 것은 아니지만, 배포가 제공하는 경우 심볼링크나 대체 메커니즘을 사용하고 있습니다.

링크할 수 있습니다.ld로.gold(로컬 바이너리 디렉토리에 있는 경우)ld덮어쓰기를 방지하기 위해 설치됨):

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

또는

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

ld와 gold의 차이 때문에 금과 호환되지 않는 프로젝트도 있는 것 같습니다.예: OpenFOAM http://www.openfoam.org/mantisbt/view.php?id=685 를 참조해 주세요.

DragonFlyBSD는 기본 링커로서 골드로 전환되었습니다.그래서 여러 가지 도구를 사용할 수 있는 것 같습니다.
상세: http://phoronix.com/scan.php?page=news_item&px=DragonFlyBSD-Gold-Linker

언급URL : https://stackoverflow.com/questions/3476093/replacing-ld-with-gold-any-experience

반응형