न्यूनतम सिंथेटिक बेंचमार्क: एलडी बनाम सोना बनाम एलएलवीएम एलएलडी
परिणाम:
-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
n_int_files="${1:-10}"
n_ints_per_file="${2:-10}"
n_funcs="${3:-10}"
cflags='-ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic'
./clean
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
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
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