wg icon indicating copy to clipboard operation
wg copied to clipboard

Selective Enabling/Disabling optimizations at a crate/file/function level

Open aclysma opened this issue 5 years ago • 6 comments

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.

aclysma avatar Jul 30 '19 03:07 aclysma

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)]

memoryruins avatar Jul 30 '19 03:07 memoryruins

This didn't work for me. Minimum reproducible example (but maybe I'm doing something wrong!): https://github.com/aclysma/mre-optimize-dependencies-only

aclysma avatar Aug 08 '19 01:08 aclysma

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.

aclysma avatar Aug 12 '19 07:08 aclysma

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

aclysma avatar Aug 22 '19 03:08 aclysma

I think that #[inline] and #[inline(always)] being copied into the use location might also affect their ability to work with profile override.

Lokathor avatar Aug 22 '19 04:08 Lokathor

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

aclysma avatar Dec 09 '19 02:12 aclysma