-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Turn off debuginfo for build dependencies to improve compile times #10493
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @ehuss (or someone else) soon. Please see the contribution instructions for more information. |
profile.opt_level = InternedString::new("0"); | ||
profile.codegen_units = None; | ||
profile.debuginfo = None; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this also add strip = "debuginfo"
on all platforms but macOS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the cargo team asked not to have strip
for now in this message.
(incidentally, a friend tried the defaults I suggested and his project saw weird errors about unstable -Z flags being used on a stable compiler, because of stripping on android, so I'm not sure that all targets can use it rn)
This looks great, thank you! The approach to showing the message seems reasonable to me. For tests that want to verify something only gets built once, turning on debug info in build-override seems reasonable.
|
Thanks Josh, I'll do so ASAP. (I've only now noticed I didn't open this PR as a draft GH PR as I intended to) |
I updated the commits about:
CI will fail because of #10500, and I'd assume this PR is kind of blocked on a resolution for that, otherwise |
e19fe05
to
fdab02e
Compare
I've reached out to @willcrichton about #10500, and turns out they had already fixed it amongst some of the changes in #10343. #10343 may involve more coordination with rustc/rustdoc, waiting for stabilization, etc., compared to this PR so I've incorporated the minimum change to fix the issue here (with proper attribution) in case it's merged first, and added a few of the #10500 cases as tests. With that fixed, and CI passing, this looks ready for review. |
Can you split the docscrape change into a separate PR? I would prefer to track and review it separately. |
Turning off debuginfo makes a noticeable difference. Backtraces in build scripts, and opting into backtraces for proc-macros on nightly, can be worse. Debuggability can be improved by changing settings back, and this will be documented for the rare cases where it's needed.
This describes the new defaults for build-overrides, and how to make sure backtraces have the usual debug info, when needed.
it's only displayed when backtraces are requested
it displays an additional message on how to improve these backtraces, now that debuginfo is turned off by default in `dev.build-override`.
Now that #10533 has landed, CI passes on this PR. |
OK, sorry, I finally got around to posting the data: https://docs.google.com/spreadsheets/d/1lru9ibjHLaXdFbROFIZXcvzXBKDDewGXjRYuvwJ0Xp8/edit?usp=sharing To read this:
There's two sets of data. The one up top is from a Linux system was 16/32 CPUs. The bottom one is from a macOS system with 6/12 CPUs (it has fewer projects since I didn't want to wait for the rest). There are little arrows in the headers where you can click to show hidden columns that contain the raw data. This includes some projects that were intentionally selected to have skewed results (those that have a high count of shared dependencies) in order to examine some potentially poor scenarios. All of them should have some proc-macros or build scripts. I find it difficult to select "real world" projects, since they tend to be difficult to find, get access to, build correctly, or take too long to build. @rust-lang/cargo Does anyone have any thoughts or conclusions you want to draw from this information? I'm still on the fence. It does look like wall clock time is improved in many situations, with a few situations made significantly worse like I feel like opportunistically sharing dependencies would be better, but I also feel like Cargo's "share things if possible" logic is already quite complex, and adding more logic to it would make it worse. |
If I'm reading this correctly, it looks like the relative improvement is small except for
I'm assuming I'm curious why we saw a difference with |
Any chance to collect more results from the new "Call For Testing" section in TWiR? |
It is my understanding that test targets are not considered "for the host", no, nor that their defaults are changed by this PR. Only build dependencies are targeted.
For Just to clarify, a high number of dependencies shared between the build-dependency subgraph and the dependency subgraph (a situation that I personally would think is less common than low-to-no sharing) is the only case where there can be regressions, and they can all be fixed by setting today's default value, to opt out of the debuginfo removal. [profile.dev.build-override]
debug = 2 The crates that would be improved by this PR (in my results, or Eric's above) could equally well apply a debuginfo-removal override to their Cargo.toml and see the benefits. So the question looks to be more about which is the better default, to fall into the "pit of success" as we know users will rarely change defaults. |
Ah, I had missed that most of those dependencies were introduced exclusively for testing, thanks for finding the actual root cause!
I agree. I feel we should prioritize individuals, local and CI. Large projects or companies will devote more resources to optimizing things. |
Closing this PR in favor of #11252. |
Turn off debuginfo for build dependencies v2 This PR is an alternative to #10493, fixing its most important issue: the unit graph optimization to reuse already built artifacts for dependencies shared between the build-time and runtime subgraphs is preserved (most of the time). By deferring the default debuginfo level in `dev.build-override` until unit graph sharing, we check whether re-use would happen. If so, we use the debuginfo level to ensure reuse does happen. Otherwise, we can avoid emitting debuginfo and improve compile times (on clean, debug and check builds -- although reuse only happens on debug builds). I've kept the message explaining how to bump the debuginfo level if an error occurs while running a build script (and backtraces were requested) that was in the previous PR. I've ran benchmarks on 800 crates, at different parallelism levels, and published the (surprisingly good) results with visualizations, summaries, and raw data [here](https://github.com/lqd/rustc-benchmarking-data/tree/main/experiments/cargo-build-defaults). Opening this PR as discussed in [Eric's message](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/Defaults.20for.20faster.20compilation.20of.20.22for.20host.22.20units/near/304236576l) as draft since 2 tests won't pass. That fixes the `cargo-crev` case we saw as a blocker last time, but doesn't fix all such cases of reuse, like the 2 failing tests: - [`optional_build_dep_and_required_normal_dep`](https://github.com/rust-lang/cargo/blob/642a0e625d10099a0ca289827de85499d073c572/tests/testsuite/build_script.rs#L4449) - and [`proc_macro_ws`](https://github.com/rust-lang/cargo/blob/bd5db301b0c45ae540afcb19e030dd7c29d2ea4f/tests/testsuite/features2.rs#L1051) These failures make sense, since the debuginfo optimization is done during traversal, it depends on the contents of the unit graph. These tests ensure that sharing happens even on finer-grained invocations: respectively, with an optional shared dependency that is later enabled, and building shared dependencies by themselves first and later as part of a complete workspace build. In both these situations, there is no unit that is shared in the graph during the first invocation, so we do the optimization and remove the debuginfo. When the graph changes in the following invocation, sharing is present and we have to build the shared units again with debuginfo. These cases feel rarer than `cargo-crev`'s case, but I do wonder if there's a way to fix them, or if it's acceptable to not support them.
This PR is a draft towards the possible state of build-override defaults described in #10481, in order to improve compile times for build dependencies (mostly proc-macros and their dependencies benefit from this):
Opening as draft for feedback and guidance:
dev
profile defaults anddev.build-override
differ on whether debuginfo is turned on, these dependencies will be built twice. To leave the tests as is, either debuginfo could be turned off, or manually set to 2, which I've done in the "tmp: update tests relying on dev and build-deps reuse" commit. I am not sure it's the expected way to do this ? Update: the test changes look acceptable so I've turned the temporary commit into a permanent one.-Zscrape-examples
: the feature seems to depend implicitly on a similar build reuse, with a mapping from for-host dependencies to regular dependencies. I'm not sure that this works correctly in all situations: it seems focused on feature flags, but reuse can also be different depending on other flags. In our case, debuginfo is now different, making some of the mapping memoization panic, causing the tests to fail. So I've temporarily disabled them in the "tmp: disable -Zscrape-examples unit tests" commit, and would need help to know what to do there. My expectation is that these panics would already happen today if someone manually opted into different debuginfo level in theirbuild-override
(or panic method, etc) but have not tested it (it seems sensible in a context where only the default settings have changed to a value users can already set). Update: This issue is now tracked in-Z rustdoc-scrape-examples
panics with some profile overrides #10500. We've discussed it with @willcrichton, and I've incorporated a fix and tests in Fix docscrape memoization #10524.Edit: with the updates above, this is ready to take out of draft.
The discussion issue #10481 also mentions the possible small
strip
addition that this PR doesn't do (and that could be done in the future), but since it's not a huge improvement, I'd say this closes #10481.