Điểm chuẩn tổng hợp tối thiểu: LD vs vàng vs LLVM LLD
Kết quả:
- vàng nhanh hơn khoảng 3 đến 4 lần đối với tất cả các giá trị tôi đã thử khi sử dụng
-Wl,--threads -Wl,--thread-count=$(nproc)
để kích hoạt đa luồng
- LLD nhanh hơn vàng khoảng gấp đôi!
Đã thử nghiệm trên:
- Ubuntu 20.04, GCC 9.3.0, binutils 2.34,
sudo apt install lld
LLD 10
- Máy tính xách tay Lenovo ThinkPad P51, CPU Intel Core i7-7820HQ (4 nhân / 8 luồng), RAM 2x Samsung M471A2K43BB1-CRC (2x 16GiB), SSD Samsung MZVLB512HAJQ-000L7 (3.000 MB / s).
Mô tả đơn giản về các thông số điểm chuẩn:
- 1: số tệp đối tượng cung cấp ký hiệu
- 2: số lượng ký hiệu trên mỗi tệp đối tượng nhà cung cấp ký hiệu
- 3: số tệp đối tượng sử dụng tất cả các ký hiệu biểu tượng được cung cấp
Kết quả cho các thông số điểm chuẩn khác nhau:
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
Đây là tập lệnh tạo tất cả các đối tượng cho các bài kiểm tra liên kết:
tạo-đối tượng
#!/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
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"
int ${func_sym}(void) {
}
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' '{}'"
GitHub ngược dòng .
Lưu ý rằng việc tạo tệp đối tượng có thể khá chậm, vì mỗi tệp C có thể khá lớn.
Cho một đầu vào kiểu:
./generate-objects [n_int_files [n_ints_per_file [n_funcs]]]
nó tạo ra:
C chính
#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;
dẫn đến:
n_int_files x n_ints_per_file x n_funcs
các vị trí trên liên kết.
Sau đó, tôi so sánh:
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
Một số giới hạn tôi đã cố gắng giảm thiểu khi chọn các thông số kiểm tra:
- ở 100k tệp C, đôi khi cả hai phương pháp đều gặp lỗi mallocs
- GCC không thể biên dịch một hàm với 1M bổ sung
Tôi cũng đã quan sát thấy mức 2x trong bản dựng gỡ lỗi của gem5: https://gem5.googlesource.com/public/gem5/+/fafe4e80b76e93e3d0d05797904c19928587f5b5
Câu hỏi tương tự: /unix/545699/what-is-the-gold-linker
Điểm chuẩn của phoronix
Phoronix đã thực hiện một số điểm chuẩn vào năm 2017 cho một số dự án trong thế giới thực, nhưng đối với các dự án mà họ đã kiểm tra, lợi nhuận vàng không quá đáng kể: https://www.phoronix.com/scan.php?page=article&item=lld4-linux-tests&num = 2 ( lưu trữ ).
Điểm không tương thích đã biết