Live data from Hacker News

Back-end parallelism in the Rust compiler

nnethercote.github.io

1–10 of 17 posts

Re: Back-end parallelism in the Rust compiler

#3
Interesting article!

Regarding the low core-count, you might actually lose performance when having less CGUs, since your absolute estimation error is larger.

For example if a CGU can take 3 times as long to compile as another with the same estimate, we might end up with a 0.75:0.25 split if we have 2 CGUs, ending up with a 50% increase in compilation time, but with 16 CGUs the worst case (one CGU taking a 1/6 of the time and 15 CGUs taking 1/18 of the time) will only result in ~11% increase in compilation time, due to the automatic balancing that job scheduling gives us.

Re: Back-end parallelism in the Rust compiler

#4
Interesting articles. For the size estimation, it might be interesting to measure what a perfect estimate would give you. Because in theory that estimate could be done based on builds in a trusted environment and saved into Cargo, especially for large popular crates.

I’m also curious if it might be possible to pipeline the CGU stage so that you feed the data from rustc to LLVM incrementally as you lower MIR into LLVM IR without having the entire CGU upfront. That may help reduce total processing time by hiding brief IO bubbles that take up a lot of time in aggregate (yes it’s CPU bound, but there’s still going to be implicit IO like memory) and also reduce total peak memory usage for hopefully obvious reasons. To gain full benefit though you might need the entire thing to be pipelined all the way through (from generating the MIR to lowering to LLVM IR) and that may be at odds with things like optimized builds which need to do analysis from a more global perspective (which would similarly inhibit the peak memory usage gains).

Re: Back-end parallelism in the Rust compiler

#5
> Setting codegen-units to 1 gives even better code quality than thin local LTO, but takes longer. Some authors of binary rust crates always use that setting for release builds because they are willing to accept the extra compile times for the highest code quality.

I wonder how many of the authors who don't use it do so because they don't know about it.

Personally, i think release builds should use codegen-units=1 by default. The meaning of a release build is "take as long as needed to build the fastest possible code". Users shouldn't have to keep track of some set of additional settings needed to achieve that. If authors want to sacrifice performance to get faster builds, or have experimentally confirmed that there is no performance impact, then they can still set codegen-units to something else.

Re: Back-end parallelism in the Rust compiler

#8
post #5

> Setting codegen-units to 1 gives even better code quality than thin local LTO, but takes longer. Some authors of binary rust crates always use that setting for release builds because they are willing to accept the extra compile times for the highest code quality. I wonder how many of the authors who don't use it do so because they don't know about it. Personally, i think release builds should use codegen-units=1 by…

> take as long as needed to build the fastest possible code

I don't think this is true. You can always go slower and produce better code.

However in practice running the compiler at the max optimization setting is very common, so maybe there is appetite for more aggressive settings at the lower cost. I do think it makes sense to add this in some preset "profile" as it doesn't have any downsides besides time. I wonder if it makes sense to do something like gzip does, where compression level 9 is made available but is very rarely worth the time trade off. Why don't compiler settings frequently go past the point where it is reasonable for most people?

Re: Back-end parallelism in the Rust compiler

#9
post #3

Interesting article! Regarding the low core-count, you might actually lose performance when having less CGUs, since your absolute estimation error is larger. For example if a CGU can take 3 times as long to compile as another with the same estimate, we might end up with a 0.75:0.25 split if we have 2 CGUs, ending up with a 50% increase in compilation time, but with 16 CGUs the worst case (one CGU taking a 1/6 of the…

I had the same thought. It may be interesting to try producing smaller CGUs then processing them on a fixed-size thread pool. This should help even out the misses. Especially if you keep a few smaller CGUs for the end, they should be "free" to give to threads that would otherwise be finished compared to merging them into a different CGU which may happen to be under-estimated and take longer.

Re: Back-end parallelism in the Rust compiler

#10
On your/the author's point about estimation of execution time, how valuable is that really? I ask because it seems like something a neural network approach could approximate. It should be relatively easy to generate a large dataset - just compile lots of libraries. Learning a function to approximate that in a small NN with a short inference time seems possible. If it's really one of the keys to getting compile time down, it's worth a shot.
Post reply on HN