ldをゴールドに置き換える-経験はありますか?


81

誰かがgold代わりに使用しようとしましたldか?

gold よりもはるかに高速であることが約束されているldため、大規模なC ++アプリケーションのテストサイクルを高速化するのに役立つ可能性がありますが、ldのドロップイン代替として使用できますか?

することができますgcc/g++直接呼び出しますかgold。?

既知のバグや問題はありますか?

が、goldしばらく以来、GNU binutilsのの一部であり、私は、Webでの「サクセスストーリー」、あるいは「ハウツー」はほとんど認められません。

更新:ゴールドへのリンクとそれを説明するブログエントリを追加しました

回答:


53

現時点では、Ubuntu10.04でより大きなプロジェクトをコンパイルしています。ここでは、簡単にインストールしてbinutils-goldパッケージと統合できます(そのパッケージを削除すると、古いものになりますld)。その場合、Gccは自動的にゴールドを使用します。

いくつかの経験:

  • 金は検索しません /usr/local/lib
  • ゴールドはpthreadやrtのようなライブラリを想定しておらず、手動で追加する必要がありました
  • それはより速く、より少ないメモリを必要とします(後者は多くのブーストなどを伴う大きなC ++プロジェクトで重要です)

動作しないもの:カーネルのものをコンパイルできないため、カーネルモジュールがありません。Ubuntuは、fglrxなどのプロプライエタリドライバーを更新する場合、DKMSを介してこれを自動的に実行します。これはで失敗しld-goldます(ゴールドを削除し、DKMSを再起動し、再インストールする必要がありますld-gold


おかげで、私はそれを試してみると思います-あなたが言及した制限は私の場合は問題ないようです。
ianH 2010

+1:経験を共有してくれてありがとう。パフォーマンスはどうですか?
ニューロ2011年

9
特に巨大な静的ライブラリを1つのバイナリにリンクする場合は非常に高速ですが、測定を困難にすることはありませんでした。
nob 2011年

2
@neuro私の測定値は、多くのオブジェクトと.aファイルを最大30個の.soファイル(1つは大きく、残りは小さい)と重要な商用アプリケーション用の1つの実行可能ファイルのセットにリンクすることでした。リンク時間のみを測定し、makeをシリアルで実行すると、ビルドあたり6.24秒の改善のために、ldで22.48秒、ゴールドで16.24秒の合計時間が得られました。ただし、makeを8個のプロセッサと並列に実行した場合、合計の差はビルドごとにわずか1.42秒です。並列化を行うかどうかに関係なく、全体的なメモリ使用量は42%向上しました。YMMV。
金属

@metal:数字をありがとう。メモリ使用量の改善は素晴らしく見えます、ldそれについてとても貪欲です。
ニューロ

40

ゴールドを選択的に使用する方法(つまり、シンボリックリンクを使用してシステム全体ではない)を見つけるのに少し時間がかかったので、ここに解決策を投稿します。これは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. 呼び出しを変更gccgcc -B$HOME/bin/goldて、gccが指定されたディレクトリで次のようなヘルパープログラムを検索しld、system-defaultの代わりにglueスクリプトを使用するようにしますld


1
それはどのオペレーティングシステムに必要ですか?nobが彼の答えで言ったように、Ubuntuの場合、ゴールドのbinutils-packageをインストールするだけで、コンパイラーはすぐにそれを使用します。openSuseについても同じです。
usr1234567 2014

8
はい、システム全体でldを置き換えるのは非常に簡単です。私の答えは、特に金を選択的に使用する方法に向けられていました。その場合、どのOSでも必要だと思います。
Tilman Vogel

1
@vidstigeはい、スクリプトの利点は、で検索するgoldことPATHです。シンボリックリンクの場合は、フルパスを指す必要があります。
Tilman Vogel

18

gcc / g ++は直接ゴールドを呼び出すことができますか?

答えを補足するためだけに、gccのオプションがあります-fuse-ld=goldgcc docを参照)。ただし、AFAIKでは、オプションが効果を持たないようにビルド中にgccを構成することは可能です。


5
-fuse-ld=gold完全ではありません。-Wl,-fuse-ld=goldリンク時に使用するのと同じように使用する必要がある場合。
nawaz 2017年

6
@Nawazいいえ、-Wl,オプションを直接ld;に渡すために使用されます。別のリンカーを使用するには、それをに伝える必要がありますgccドキュメントを参照してください。
calandoa

11

Samba開発者として、私は数年前からUbuntu、Debian、Fedoraでほぼ独占的にゴールドリンカーを使用しています。私の評価:

  • 金は古典的なリンカーよりも何倍も速い(感じ:5-10倍)。
  • 当初、いくつかの問題がありましたが、おおよそUbuntu12.04以降問題が発生しています。
  • ゴールドリンカーは、いくつかの詳細に関して古典的なものよりも正しいように見えるため、コードにいくつかの依存関係の問題さえ発見しました。たとえば、このSambaコミットを参照してください。

私は金を選択的に使用していませんが、ディストリビューションが提供する場合はシンボリックリンクまたは代替メカニズムを使用しています。


9

あなたはリンクできldgold(あなたがしている場合、ローカルのバイナリディレクトリにld上書きされないようにインストールされています):

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

または

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

6

最小限の合成ベンチマーク:LDvsゴールドvsLLVM LLD

結果:

  • -Wl,--threads -Wl,--thread-count=$(nproc)マルチスレッドを有効にするために使用したときに試したすべての値で、ゴールドは約3倍から4倍高速でした
  • LLDは金の約2倍速かったです!

テスト済み:

  • Ubuntu 20.04、GCC 9.3.0、binutils 2.34、sudo apt install lldLLD 10
  • Lenovo ThinkPad P51ラップトップ、Intel Core i7-7820HQ CPU(4コア/ 8スレッド)、2x Samsung M471A2K43BB1-CRC RAM(2x 16GiB)、Samsung MZVLB512HAJQ-000L7 SSD(3,000MB /秒)。

ベンチマークパラメータの簡単な説明:

  • 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]]]

それは生成します:

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;

これは次のことにつながります:

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アーカイブ)。

既知の非互換性

LLDベンチマーク

https://lld.llvm.org/彼らはいくつかのよく知られたプロジェクトのビルド時間を与えます。私の合成ベンチマークと同様の結果が得られました。残念ながら、プロジェクト/リンカーのバージョンは提供されていません。彼らの結果では:

  • 金はLDより約3倍/ 4倍速かった
  • LLDはゴールドよりも3倍/ 4倍速かったので、私の合成ベンチマークよりも大幅に高速化されました

彼らはコメントします:

これは、SSDドライブを備えた2ソケット20コア40スレッドXeon E5-2680 2.80GHzマシンでのリンク時間の比較です。マルチスレッドのサポートの有無にかかわらず、ゴールドと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

1
私はあなたの発見を確認することができます、私は私のプロジェクトをリンクするための同様のスピードアップを見ます。こちらのベンチマークも参照してくださいlld.llvm.org
ypnos20年

3

ldとgoldの間に互換性のない違いがあるため、一部のプロジェクトはゴールドと互換性がないようです。例:OpenFOAM、http://www.openfoam.org/mantisbt/view.php id = 685を参照してください


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.