The linked paper about the design of Mold at https://arxiv.org/pdf/2608.23228 is also really interesting reading, too. I hope that at some point Wild's authors also publish some bragging writing about how their software works and what makes it fast. ❤️
I am wondering whether there's strong interest by the authors if these new fast linkers in changing how compilers interface with them to speed up the linking stage. The first thing that comes to mind would be cooperating on file formats that might be cheaper for the compiler to produce and/or for the linker to consume. A second idea might be to have the compiler start feeding input to the linker as soon as partial input is available, so that linking can be partially pipelined with compilation.
"But this is largely due to Wild lacking the OS-specific tweaks that make creation and writing of a new file on non-tmpfs filesystems fast." lld also lacks such tweaks.
In addition, I don't like forking as the default behavior. mold/wild stops being a well-behaved process for anything that reasons about process trees:
getrusage(RUSAGE_CHILDREN), /usr/bin/time -v, shell time - all report the parent, which did nothing. Peak RSS in particular is meaningless.
perf stat, strace -f, gdb need extra care or --no-fork.
With ninja -j N, the scheduler frees the job slot while the orphan still holds its full RSS. Several concurrent links can leave you with a peak memory footprint well above what the build system thinks it has committed.
% hyperfine -w 1 -r 10 -c 'rm -f /dev/shm/a.out' -n wild0 'numactl -C 0-7 /data/code/wild/target/release/wild --no-fork --threads=8 @response.txt -o /dev/shm/a.out' -n mold1 'numactl -C 0,2,4,6,8,10,12,14 /data/code/wild/target/release/wild --no-fork --threads=8 @response.txt -o /dev/shm/a.out'
Benchmark 1: wild0
Time (mean ± σ): 899.2 ms ± 21.5 ms [User: 4574.9 ms, System: 1367.9 ms]
Range (min … max): 873.8 ms … 938.1 ms 10 runs
Benchmark 2: mold1
Time (mean ± σ): 708.9 ms ± 12.2 ms [User: 3373.1 ms, System: 1077.5 ms]
Range (min … max): 695.8 ms … 728.5 ms 10 runs
Summary
mold1 ran
1.27 ± 0.04 times faster than wild0
(using system libmimalloc.so.3.5, LLVM_ENABLE_PIC=off)
% hyperfine -w 1 -r 10 -c 'rm -f /dev/shm/a.out' -n lld0 'numactl -C 0-7 /tmp/out/custom1/bin/ld.lld --threads=8 @response.txt -o /dev/shm/a.out' -n lld1 'numactl -C 0,2,4,6,8,10,12,14 /tmp/out/custom1/bin/ld.lld --threads=8 @response.txt -o /dev/shm/a.out'
Benchmark 1: lld0
Time (mean ± σ): 1.766 s ± 0.034 s [User: 4.204 s, System: 1.154 s]
Range (min … max): 1.734 s … 1.826 s 10 runs
Benchmark 2: lld1
Time (mean ± σ): 1.756 s ± 0.024 s [User: 3.881 s, System: 0.895 s]
Range (min … max): 1.721 s … 1.784 s 10 runs
Summary
lld1 ran
1.01 ± 0.02 times faster than lld0
I maintain lld, and my reaction to the 2.4x+ range in the mold paper was that it reads harsher than what I see day to day.
In my own use lld time is typically below 2x mold; I don't think I've ever observed 4x.
Two of the largest ratios come from specific lld deficiencies rather than from its architecture:
--version-script matching was not parallel. This is what makes TensorFlow/PyTorch shared objects look catastrophic. I've parallelized it in https://github.com/llvm/llvm-project/pull/223208 (will be included in lld 24)
arxiv
--icf=all is slow. In Chromium configurations that enable it, about half of lld's link time goes to ICF. I have a patch pending.
Is the difference in numactl args intentional in your first comparison between wild/mold.
I'm not familiar but to the untrained eye it looks like for mold you have maybe allocated threads not sharing physical CPUs but for wild you have not?
The first hyperfine command has a typo. It compares numactl -C 0-7 (8 threads on 4 P-cores using hyper-threading) and numactl -C 0,2,4,6,8,10,12,14 (8 threads on 8 distinct P-cores).
Both mold and wild drop by ~30–40% when forced to share SMT pairs rather than dedicated cores. ld.lld shows no real SMT sensitivity since it doesn't saturate thread capacity. Note that lld isn't as slow as the mold paper implies. Reaching an lld/mold time ratio greater than 2x is difficult in real-world testing.
0x2ba22e11 | 21 hours ago
The linked paper about the design of Mold at https://arxiv.org/pdf/2608.23228 is also really interesting reading, too. I hope that at some point Wild's authors also publish some
braggingwriting about how their software works and what makes it fast. ❤️I am wondering whether there's strong interest by the authors if these new fast linkers in changing how compilers interface with them to speed up the linking stage. The first thing that comes to mind would be cooperating on file formats that might be cheaper for the compiler to produce and/or for the linker to consume. A second idea might be to have the compiler start feeding input to the linker as soon as partial input is available, so that linking can be partially pipelined with compilation.
[OP] goldstein | 20 hours ago
I think Zig has an incremental linker: https://ziglang.org/download/0.16.0/release-notes.html#Incremental-Compilation
MaskRay | 7 hours ago
"But this is largely due to Wild lacking the OS-specific tweaks that make creation and writing of a new file on non-tmpfs filesystems fast." lld also lacks such tweaks.
In addition, I don't like forking as the default behavior. mold/wild stops being a well-behaved process for anything that reasons about process trees:
getrusage(RUSAGE_CHILDREN),/usr/bin/time -v, shell time - all report the parent, which did nothing. Peak RSS in particular is meaningless.perf stat,strace -f,gdbneed extra care or --no-fork.ninja -j N, the scheduler frees the job slot while the orphan still holds its full RSS. Several concurrent links can leave you with a peak memory footprint well above what the build system thinks it has committed.MaskRay | 7 hours ago
(cargo build --release, system malloc)
(using system libmimalloc.so.3.5, LLVM_ENABLE_PIC=off)
I maintain lld, and my reaction to the 2.4x+ range in the mold paper was that it reads harsher than what I see day to day. In my own use lld time is typically below 2x mold; I don't think I've ever observed 4x.
Two of the largest ratios come from specific lld deficiencies rather than from its architecture:
reivilibre | an hour ago
Is the difference in
numactlargs intentional in your first comparison betweenwild/mold. I'm not familiar but to the untrained eye it looks like for mold you have maybe allocated threads not sharing physical CPUs but for wild you have not?MaskRay | 32 minutes ago
The first hyperfine command has a typo. It compares
numactl -C 0-7(8 threads on 4 P-cores using hyper-threading) andnumactl -C 0,2,4,6,8,10,12,14(8 threads on 8 distinct P-cores).Both mold and wild drop by ~30–40% when forced to share SMT pairs rather than dedicated cores. ld.lld shows no real SMT sensitivity since it doesn't saturate thread capacity. Note that lld isn't as slow as the mold paper implies. Reaching an lld/mold time ratio greater than 2x is difficult in real-world testing.
gir | 17 hours ago
gold,wild,mold... i'm starting to see a pattern here :^)any predictions for the next one?
[OP] goldstein | 16 hours ago
paid version of mold (used to?) be called sold
5d22b | 15 hours ago
The pattern starts with the standard Unix linker being named
ldand also includes the LLVM linker being namedlld.gir | 14 hours ago
Yep, aware