सोने के साथ ld की जगह - कोई अनुभव?


81

क्या किसी ने goldइसके बजाय उपयोग करने की कोशिश की है ld?

gold की तुलना में बहुत तेज होने का वादा करता है ld, इसलिए यह बड़े C ++ अनुप्रयोगों के लिए परीक्षण चक्रों को गति देने में मदद कर सकता है, लेकिन क्या इसका उपयोग ld के लिए ड्रॉप-इन प्रतिस्थापन के रूप में किया जा सकता है?

gcc/ g++सीधे कॉल कर सकते हैं gold

वहाँ किसी भी कीड़े या समस्याओं को जानते हैं?

हालाँकि goldकुछ समय से जीएनयू बिन्यूटिल का हिस्सा है, लेकिन मुझे वेब में लगभग कोई "सफलता की कहानियां" या यहां तक ​​कि "हाउटोस" नहीं मिला है।

( अद्यतन: यह बताते हुए सोने और ब्लॉग प्रविष्टि में लिंक जोड़े गए )

जवाबों:


53

फिलहाल यह उबंटू 10.04 पर बड़ी परियोजनाओं को संकलित कर रहा है। यहां आप इसे binutils-goldपैकेज के साथ आसानी से स्थापित और एकीकृत कर सकते हैं (यदि आप उस पैकेज को हटाते हैं, तो आप अपना पुराना प्राप्त करते हैं ld)। Gcc स्वतः सोने का उपयोग करेगा।

कुछ अनुभव:

  • सोने में खोज नहीं है /usr/local/lib
  • सोने को पीथ्रेड या आरटी की तरह लिबास नहीं लगता है, उन्हें हाथ से जोड़ना था
  • यह तेज़ है और इसे कम मेमोरी की आवश्यकता है (बाद में बड़े C ++ प्रोजेक्ट्स पर बहुत अधिक बढ़ावा आदि के साथ महत्वपूर्ण है)

क्या काम नहीं करता है: यह कर्नेल सामग्री को संकलित नहीं कर सकता है और इसलिए कोई कर्नेल मॉड्यूल नहीं है। अगर यह मालिकाना ड्राइवरों जैसे fglrx को अपडेट करता है, तो Ubuntu DKK के माध्यम से स्वचालित रूप से करता है। इसके साथ विफल रहता है ld-gold(आपको सोना निकालना होगा, DKMS को पुनरारंभ करना होगा, फिर से इंस्टॉल करना होगा ld-gold


धन्यवाद, मुझे लगता है कि मैं इसे एक कोशिश दूँगा - आपके द्वारा उल्लिखित प्रतिबंध मेरे मामले में कोई समस्या नहीं है।
IanH

+1: अनुभव साझा करने के लिए धन्यवाद। प्रदर्शन के बारे में क्या?
न्यूरो

9
यह काफी तेज है, विशेष रूप से विशाल स्थिर पुस्तकालयों को एक बाइनरी से जोड़ने पर, लेकिन हमने किसी भी माप को कठिन नहीं बनाया।
nob

2
@neuro मेरे माप कई वस्तुओं और .a फ़ाइलों को ~ 30 .so फ़ाइलों (एक लार्जिश, बाकी छोटे) के सेट में और एक महत्वपूर्ण व्यावसायिक अनुप्रयोग के लिए 1 निष्पादन योग्य बनाने के लिए थे। केवल लिंक समय को मापने और धारावाहिक में रन बनाने से, मुझे 6.24 सेकंड प्रति निर्माण के सुधार के लिए सोने के साथ ld बनाम 16.24 सेकंड के साथ कुल 22.48 सेकंड का समय मिला। हालांकि, अगर मैं 8 प्रोसेसर के साथ मेक-अप रन करता हूं, तो कुल अंतर केवल 1.42 सेकंड प्रति निर्माण है। समांतर बनाने की परवाह किए बिना समग्र स्मृति उपयोग 42% सुधार था। YMMV।
धातु

@ धातु: आंकड़ों के लिए बहुत बहुत धन्यवाद। स्मृति उपयोग सुधार बहुत अच्छा लग रहा है, ldइसके बारे में इतना लालची है।
न्यूरो

40

चूंकि मुझे यह पता लगाने में थोड़ा समय लगा कि सोने का चयन कैसे किया जाए (यानी सिम्बलिन का उपयोग करके सिस्टम-वाइड नहीं), मैं यहां समाधान पोस्ट करूंगा। यह http://code.google.com/p/chromium/wiki/LinuxFasterBuilds#Linking_use_old पर आधारित है ।

  1. एक निर्देशिका बनाएं जहां आप एक सोने की गोंद स्क्रिप्ट रख सकते हैं। मैं उपयोग कर रहा हूं ~/bin/gold/
  2. निम्नलिखित गोंद लिपि को वहां रखें और नाम दें ~/bin/gold/ld:

    #!/bin/bash
    gold "$@"
    

    जाहिर है, इसे निष्पादन योग्य बनाओ chmod a+x ~/bin/gold/ld,।

  3. अपने कॉल करने के लिए परिवर्तित gccकरने के लिए gcc -B$HOME/bin/goldजो की तरह सहायक कार्यक्रमों के लिए दिए गए निर्देशिका में जीसीसी देखो बनाता है ldऔर इस प्रकार प्रणाली-डिफ़ॉल्ट के बजाय गोंद स्क्रिप्ट का उपयोग करता है ld


1
यह किस ऑपरेटिंग सिस्टम के लिए आवश्यक है? जैसा कि नॉब ने अपने जवाब में कहा, उबंटू के लिए बस सोने के बिन्यूटिल्स-पैकेज स्थापित करें और संकलक इसे तुरंत उपयोग करेंगे। OpenSuse के लिए भी।
usr1234567

8
हां, ld सिस्टम-वाइड को बदलना काफी आसान है। मेरा उत्तर विशेष रूप से सोने का उपयोग करने के तरीके के प्रति था। और उस मामले में, मुझे लगता है, यह किसी भी ओएस के लिए आवश्यक है।
तिलमन वोगेल

1
@vidstige हां, स्क्रिप्ट का फायदा यह है कि यह goldइस पर दिखता है PATH। एक सिमलिंक के लिए, आपको पूर्ण पथ की ओर इशारा करना होगा।
तिलमन वोगेल

18

क्या gcc / g ++ सीधे सोना कह सकता है।

बस जवाबों को पूरक करने के लिए: एक जीसीसी विकल्प है -fuse-ld=gold( जीसीसी डॉक्टर देखें )। हालांकि, AFAIK, बिल्ड के दौरान gcc को इस तरह से कॉन्फ़िगर करना संभव है कि विकल्प पर कोई प्रभाव नहीं पड़ेगा।


5
-fuse-ld=goldपूरा नहीं हुआ है। यदि आपको -Wl,-fuse-ld=goldलिंक-टाइम पर इसका उपयोग करना है।
नवाज

6
@ नवाज़ नो, -Wl,का उपयोग सीधे किसी विकल्प को पास करने के लिए किया जाता है ld; एक और लिंकर उपयोग करने के लिए आप के लिए है कि बताने के लिए की जरूरत है gcc। कृपया डॉक का संदर्भ लें ।
कैलेंडोए

11

सांबा डेवलपर के रूप में, मैं कई वर्षों के बाद से अब तक उबंटू, डेबियन और फेडोरा पर लगभग विशेष रूप से गोल्ड लिंकर का उपयोग कर रहा हूं। मेरा आकलन:

  • शास्त्रीय लिंकर की तुलना में सोना कई बार (महसूस किया जाता है: 5-10 गुना) तेजी से होता है।
  • प्रारंभ में, कुछ समस्याएं थीं, लेकिन लगभग 12.04 उबंटू के बाद से चले गए हैं।
  • गोल्ड लिंकर को हमारे कोड में कुछ निर्भरता की समस्याएं भी मिलीं, क्योंकि यह कुछ विवरणों के संबंध में शास्त्रीय एक से अधिक सही प्रतीत होता है। देखें, उदाहरण के लिए यह सांबा प्रतिबद्ध है

मैंने सोने का चयन चुनिंदा तरीके से नहीं किया है, लेकिन अगर वितरण प्रदान करता है, तो यह सीमलिंक या विकल्प तंत्र का उपयोग कर रहा है।


9

आप एक स्थानीय बाइनरी निर्देशिका में लिंक ldकर सकते हैं gold(यदि आपने ldओवरराइटिंग से बचने के लिए स्थापित किया है):

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

या

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

6

न्यूनतम सिंथेटिक बेंचमार्क: एलडी बनाम सोना बनाम एलएलवीएम एलएलडी

परिणाम:

  • -Wl,--threads -Wl,--thread-count=$(nproc)मल्टीथ्रेडिंग को सक्षम करने के लिए उपयोग किए जाने वाले सभी मूल्यों के लिए सोना लगभग 3x से 4x तेज था
  • सोने की तुलना में एलएलडी 2 गुना तेज था!

पर परीक्षण किया गया:

  • उबंटू 20.04, जीसीसी 9.3.0, बिनुटिल्स 2.34, sudo apt install lldएलएलडी 10
  • लेनोवो थिंकपैड P51 लैपटॉप, इंटेल कोर i7-7820HQ सीपीयू (4 कोर / 8 थ्रेड्स), 2x सैमसंग M471A2K43BB1-CRC RAM (2x 16GiB), सैमसंग MZVLB12HAJQ-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' '{}'"

गिटहब ऊपर

ध्यान दें कि ऑब्जेक्ट फ़ाइल पीढ़ी काफी धीमी हो सकती है, क्योंकि प्रत्येक सी फ़ाइल काफी बड़ी हो सकती है।

प्रकार के इनपुट को देखते हुए:

./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. सी, 1. सी, ..., <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 फाइलों में, दोनों विधियाँ कभी-कभी विफल हो जाती हैं
  • GCC एक फ़ंक्शन को 1M अतिरिक्त के साथ संकलित नहीं कर सकता है

मैंने gem5 के डिबग बिल्ड में एक 2x भी देखा है: https://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c1b28587f5b5

इसी तरह के सवाल: /unix/545699/what-is-the-gold-linker

Phoronix मानदंड

Phoronix ने 2017 में कुछ वास्तविक विश्व परियोजनाओं के लिए कुछ बेंचमार्किंग की, लेकिन जिन परियोजनाओं की उन्होंने जांच की, उनमें सोने का लाभ इतना महत्वपूर्ण नहीं था: https://www.phoronix.com/scan.php?page=article&item=lld4-linux-tests&num = 2 ( संग्रह )।

ज्ञात असंगतताएँ

एलएलडी बेंचमार्क

पर https://lld.llvm.org/ वे कुछ प्रसिद्ध परियोजनाओं के लिए निर्माण के समय देते हैं। मेरे सिंथेटिक बेंचमार्क के समान परिणाम के साथ। परियोजना / लिंकर संस्करण दुर्भाग्य से नहीं दिए गए हैं। उनके परिणामों में:

  • सोना LD की तुलना में लगभग 3x / 4x तेज था
  • एलएलडी सोने की तुलना में 3x / 4x तेज था, इसलिए मेरे सिंथेटिक बेंचमार्क की तुलना में अधिक गति थी

वे टिप्पणी करते हैं:

यह SSD ड्राइव के साथ 2-सॉकेट 20-कोर 40-थ्रेड Xeon E5-2680 2.80 GHz मशीन पर लिंक समय की तुलना है। हम बहु-थ्रेडिंग समर्थन के साथ या इसके बिना सोना और बड़े भागते हैं। मल्टी-थ्रेडिंग को अक्षम करने के लिए, हमने -इन-थ्रेड्स को कमांड लाइनों में जोड़ा।

और परिणाम इस तरह दिखते हैं:

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
मैं आपके निष्कर्षों की पुष्टि कर सकता हूं, मैं अपनी परियोजनाओं को जोड़ने के लिए समान गति देखता हूं। यहाँ भी देखें lmark.llvm.org
ypnos


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.