-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bootstrap is slow #126423
Comments
This also annoys me. I'll try to profile it in a bit more detail. |
Seems like about a half of that duration on Linux is spent inside Edit: this only happens if you set |
Apart from stripping, the rest is #126467 + a bunch of cargo and git invocations, but that was already clear from the flamechart. |
…=Kobzol build `libcxx-version` only when it doesn't exist In rust-lang#126423, it seems like c++ parsing takes quite amount of time on bootstrap startups. This PR makes libcxx-version to be compiled only when it doesn't exist. A simple demonstration on the overhead of buiding `libcxx-version`: ```sh $ rm -rf build/host/libcxx-version $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 509ms Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.25s Build completed successfully in 0:00:02 $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 2ms Creating a sysroot for stage2 compiler (use `rustup toolchain link 'name' build/host/stage2`) Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.14s Build completed successfully in 0:00:01 ```
…=Kobzol build `libcxx-version` only when it doesn't exist In rust-lang#126423, it seems like c++ parsing takes quite amount of time on bootstrap startups. This PR makes libcxx-version to be compiled only when it doesn't exist. A simple demonstration on the overhead of buiding `libcxx-version`: ```sh $ rm -rf build/host/libcxx-version $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 509ms Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.25s Build completed successfully in 0:00:02 $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 2ms Creating a sysroot for stage2 compiler (use `rustup toolchain link 'name' build/host/stage2`) Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.14s Build completed successfully in 0:00:01 ```
The
And based on the flamegraph above, most of the runtime of git is in process startup. Caching these somehow seems sensible. |
…=Kobzol build `libcxx-version` only when it doesn't exist In rust-lang#126423, it seems like c++ parsing takes quite amount of time on bootstrap startups. This PR makes libcxx-version to be compiled only when it doesn't exist. A simple demonstration on the overhead of buiding `libcxx-version`: ```sh $ rm -rf build/host/libcxx-version $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 509ms Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.25s Build completed successfully in 0:00:02 $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 2ms Creating a sysroot for stage2 compiler (use `rustup toolchain link 'name' build/host/stage2`) Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.14s Build completed successfully in 0:00:01 ```
That's a good point! Onur has an open PR that centralizes the git invocations in bootstrap, once that's merged, it will be easier to cache them, I'll take a look at it. Also, running |
…=Kobzol build `libcxx-version` only when it doesn't exist In rust-lang#126423, it seems like c++ parsing takes quite amount of time on bootstrap startups. This PR makes libcxx-version to be compiled only when it doesn't exist. A simple demonstration on the overhead of buiding `libcxx-version`: ```sh $ rm -rf build/host/libcxx-version $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 509ms Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.25s Build completed successfully in 0:00:02 $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 2ms Creating a sysroot for stage2 compiler (use `rustup toolchain link 'name' build/host/stage2`) Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.14s Build completed successfully in 0:00:01 ```
Rollup merge of rust-lang#126472 - onur-ozkan:improve-libcxx-build, r=Kobzol build `libcxx-version` only when it doesn't exist In rust-lang#126423, it seems like c++ parsing takes quite amount of time on bootstrap startups. This PR makes libcxx-version to be compiled only when it doesn't exist. A simple demonstration on the overhead of buiding `libcxx-version`: ```sh $ rm -rf build/host/libcxx-version $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 509ms Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.25s Build completed successfully in 0:00:02 $ x build Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.07s ----- LIBCXX VERSION CHECK TOOK: 2ms Creating a sysroot for stage2 compiler (use `rustup toolchain link 'name' build/host/stage2`) Building tool rustdoc (stage1 -> stage2, x86_64-unknown-linux-gnu) Finished `release` profile [optimized] target(s) in 0.14s Build completed successfully in 0:00:01 ```
Why are we re-stripping when things are cached? |
It happens unconditionally, so it is performed even if the build itself is cached. But I forgot to write here that this only seems to be happening with relatively old versions of |
Also these numbers are dependent on one's config debug options, linker/strip version, etc, and no stripping happens when some debuginfo is requested for the compiler or libstd; that is not a universal overhead. It doesn't look like a noticeable part of the OP's flamegraph and certainly not half of the time. That stripping should also only be applied to dist artifacts, there's no need to do that locally. Unfortunately, in the current state of bootstrap, it's unexpectedly hard to achieve, both Jakub and I tried and it always caused issues elsewhere, and hopefully that can be fixed in the future. |
A fully cached
./x run --stage 1 miri
takes 2.35s. This is really slow, and added to most bootstrap invocations.Bootstrap is doing a lot of work, and it's nontrivial to optimize all of that, but it leads to these slow times.
There's not gonna be a silver bullet, but I believe this is something we should at least consider and attempt to improve if possible.
One particularly slow aspect is updating the submodules. Another thing I found in my profile is that it spends 10% of the time parsing C++. I do not think every bootstrap invocation should involve parsing C++ code. There's also lots of overhead from cargo, maybe there are unnecessary cargo invocations?
I've attached the flamegraph from
perf record --call-graph=dwarf ./x run --stage 1 miri
.The text was updated successfully, but these errors were encountered: