wg
wg copied to clipboard
Selective Enabling/Disabling optimizations at a crate/file/function level
Many C++ compilers allow disabling the optimizer for a span of code with a #pragma. I can think of a few use-cases, but there may be others:
- I would like to have optimizations on for all upstream crates, but off for my own code to improve build times and debugging experience. (In a big project, I might want to turn optimizations off for just some of my codebase.)
- If I had a large codebase, I might need the optimizer to reduce the binary size to fit on a target device.
If this functionality does not exist (or is not yet stable), and others here agree that it's worth pursuing, it might be worth raising this with the core rust team so that they know it's of interest to us.
If it does exist, then it may be worth trying to share more broadly that this is possible.
- This could be in the form of general guidance (i.e. reddit or blog post)
- We could recommend to those authoring crates that they mention this in their readme. It's best if people new to the ecosystem have a good initial experience, and they may not be aware of how much faster optimized Rust is than unoptimized.
Two nightly features that may be of interest:
cargo profile overrides: https://doc.rust-lang.org/cargo/reference/unstable.html#profile-overrides
Profiles can be overridden for specific packages and custom build scripts.
# the `image` crate will be compiled with -Copt-level=3
[profile.dev.overrides.image]
opt-level = 3
and #![feature(optimize_attribute)]
:
https://github.com/rust-lang/rfcs/blob/master/text/2412-optimize-attr.md
This RFC introduces the #[optimize] attribute for controlling optimization level on a per-item basis. With the #[optimize] attribute it is possible to annotate the optimization level of separate items, so that they are optimized differently from the global optimization option.
e.g. #[optimize(size)]
#[optimize(speed)]
This didn't work for me. Minimum reproducible example (but maybe I'm doing something wrong!): https://github.com/aclysma/mre-optimize-dependencies-only
I did more investigation on this. The MRE now demonstrates that depending on the optimization level of the caller, the function in the upstream crate may not be optimized. It makes me think I'm getting both debug and release versions of that crate linked into the binary. There is a tracking issue here (https://github.com/rust-lang/rust/issues/48683) for the feature. Maybe I'm doing this incorrectly, or my expectations of what should happen aren't right, but it seems like the feature is broken.
An update for anyone watching this.. I opened an issue here: https://github.com/rust-lang/rust/issues/63484. It seems like generics do not play well with profile overrides (and in my case, I was hoping for nphysics to be optimized, and nearly everything in that library is generic.
I also saw that the embark rust ecosystem repo had a bug open for this as well: https://github.com/EmbarkStudios/rust-ecosystem/issues/5
So main issues for profile overrides are:
- Requires nightly, since it's not a stabilized feature
- Certain generic-heavy crates might not get optimized using this method
I think that #[inline]
and #[inline(always)]
being copied into the use location might also affect their ability to work with profile override.
Profile overrides is set to be stabilized in 1.41 (https://github.com/rust-lang/cargo/pull/7591)
In practice, -Zshare-generics=yes
will be required to optimize generics, the comment here is worth reading: https://github.com/rust-lang/rust/issues/63484#issuecomment-529701283