According to the readme, Rust is supported, did anyone tried and noticed improvement? rui314/mold: Mold: A Modern Linker 🦠 https://github.com/rui314/mold
codegen-units=1
,debug=true
, varyinglto
lto = "fat"
Flags Clean build time Pre-strip size Post-strip size (default) 2:31 90.8207MiB 7.3374MiB ["-Z", "gcc-ld=lld"]
2:31 91.9731MiB 7.3332MiB linker = "clang"
2:32 90.8207MiB 7.3375MiB linker = "clang"; fuse-ld="mold"
2:31 92.1107MiB 7.3334MiB lto = "thin"
Flags Clean build time Pre-strip size Post-strip size (default) 1:33 96.9630MiB 8.1695MiB ["-Z", "gcc-ld=lld"]
1:32 98.3889MiB 8.1777MiB linker = "clang"
1:33 96.9631MiB 8.1695MiB linker = "clang"; fuse-ld="mold"
1:32 98.6903MiB 8.1797MiB lto = false
Flags Clean build time Pre-strip size Post-strip size (default) 1:32 113.5656MiB 8.0601MiB ["-Z", "gcc-ld=lld"]
1:30 115.1210MiB 8.1122MiB linker = "clang"
1:32 113.5656MiB 8.0602MiB linker = "clang"; fuse-ld="mold"
1:31 115.4679MiB 8.0663MiB lto = "off"
Flags Clean build time Pre-strip size Post-strip size (default) 1:33 113.5666MiB 8.0601MiB ["-Z", "gcc-ld=lld"]
1:31 115.1231MiB 8.1122MiB linker = "clang"
1:32 113.5667MiB 8.0602MiB linker = "clang"; fuse-ld="mold"
1:31 115.4697MiB 8.0662MiB codegen-units=8
,debug=true
, varyinglto
lto = "fat"
Flags Clean build time Pre-strip size Post-strip size (default) 2:21 104.9842MiB 7.6304MiB ["-Z", "gcc-ld=lld"]
2:19 106.1436MiB 7.6264MiB linker = "clang"
2:21 104.9882MiB 7.6344MiB linker = "clang"; fuse-ld="mold"
2:19 106.2864MiB 7.6325MiB lto = "thin"
Flags Clean build time Pre-strip size Post-strip size (default) 1:12 134.1112MiB 9.0445MiB ["-Z", "gcc-ld=lld"]
1:09 136.1897MiB 9.0660MiB linker = "clang"
1:12 134.1113MiB 9.0446MiB linker = "clang"; fuse-ld="mold"
1:09 136.4466MiB 9.0494MiB lto = false
Flags Clean build time Pre-strip size Post-strip size (default) 1:14 158.1049MiB 9.0328MiB ["-Z", "gcc-ld=lld"]
1:11 159.9998MiB 9.1129MiB linker = "clang"
1:14 158.1050MiB 9.0328MiB linker = "clang"; fuse-ld="mold"
1:12 160.3123MiB 9.0428MiB lto = "off"
Flags Clean build time Pre-strip size Post-strip size (default) 0:57 145.9463MiB 9.4586MiB ["-Z", "gcc-ld=lld"]
0:54 148.6021MiB 9.6001MiB linker = "clang"
0:57 145.9464MiB 9.4587MiB linker = "clang"; fuse-ld="mold"
0:55 148.8842MiB 9.4668MiB
mold
appears to be similar but not faster thanlld
.With the caveat that this is not a proper benchmark since:
- I didn’t measure link time alone.
- I didn’t bother running each case multiple times picking the fastest run (since I perceived the differences to be insignificant).
And a side note,
lto = false
appears to be practically useless.-
With a total build time of less than 2 minutes, my guess is that link time is fairly small. At work we have a c++ project that takes around 40 minutes to build. Only in the incremental case does link time dominate (upwards of 10 seconds with gold, haven’t tried lld or mold).
-
My understanding is that mold supposedly has more scalable data structures and algorithms (better complexity). Thus for small links there likely will be little difference. So you need to measure it on your actual use case to see if it makes a difference.
-
mold supposedly can take more advantage of multi core. How many cores did you run on? Again this will likely not show for small links, since there is also overhead in splitting work across threads.
Okay. I updated mold to
v2.0.0
. Added"-Z", "time-passes"
to get link times, ran cargo with--timings
to get CPU utilization graphs. Tested on two projects of mine (the one from yesterday is “X”).Link times are picked as the best from 3-4 runs, changing only white space on
main.rs
.lto="fat"
lld mold project X (cu=1) 105.923 106.380 Project X (cu=8) 103.512 103.513 Project S (cu=1) 94.290 94.969 Project S (cu=8) 100.118 100.449 Observations (
lto="fat"
): As expected, not a lot of utilization of multi-core. Usingcodegen-units
larger than 1 may even cause a regression in link time. Choice of linker betweenlld
andmold
appears to be of no significance.
lto="thin"
lld mold project X (cu=1) 46.596 47.118 Project X (cu=8) 34.167 33.839 Project X (cu=16) 36.296 36.621 Project S (cu=1) 41.817 41.404 Project S (cu=8) 32.062 32.162 Project S (cu=16) 35.780 36.074 Observations (
lto="thin"
): Here, we see parallelLLVM_lto_optimize
runs kicking in. Testing withcodegen-units=16
was also done. In that case, the number of parallelLLVM_lto_optimize
runs was so big, the synchronization overhead caused a regression running that test on a humble workstation powered by an Intel i7-7700K processor (4 physical, 8 logical cores only). The results will probably look different running this test case (cu=16) in a more powerful setup. But still, the choice of linker betweenlld
andmold
appears to be of no significance.
lto=false
lld mold project X (cu=1) 29.160 29.231 Project X (cu=8) 8.130 8.293 Project X (cu=16) 7.076 6.953 Project S (cu=1) 11.996 12.069 Project S (cu=8) 4.418 4.462 Project S (cu=16) 4.357 4.455 Observations (
lto=false
): Here,codegen-units
becomes the dominant factor with no heavyLLVM_lto_optimize
runs involved. Going abovecodegen-units=8
does not hurt link time. Still, the choice of linker betweenlld
andmold
appears to be of no significance.
lto="off"
lld mold project X (cu=1) 29.109 29.201 Project X (cu=8) 5.896 6.117 Project X (cu=16) 3.479 3.637 Project S (cu=1) 11.732 11.742 Project S (cu=8) 2.354 2.355 Project S (cu=16) 1.517 1.499 Observations (
lto="off"
): Same observations aslto=false
. Still, the choice of linker betweenlld
andmold
appears to be of no significance.
Debug builds link in <.4 seconds.
-