Skip to content
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

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

Open
aclysma opened this issue Jul 30, 2019 · 6 comments
Open

Comments

@aclysma
Copy link
Contributor

aclysma commented Jul 30, 2019

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.
@memoryruins
Copy link

memoryruins commented Jul 30, 2019

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

@aclysma
Copy link
Contributor Author

aclysma commented Aug 8, 2019

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
Copy link
Contributor Author

aclysma commented Aug 12, 2019

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 (rust-lang/rust#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
Copy link
Contributor Author

aclysma commented Aug 22, 2019

An update for anyone watching this.. I opened an issue here: rust-lang/rust#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:
EmbarkStudios/rust-ecosystem#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

@Lokathor
Copy link
Member

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

@aclysma
Copy link
Contributor Author

aclysma commented Dec 9, 2019

Profile overrides is set to be stabilized in 1.41 (rust-lang/cargo#7591)

In practice, -Zshare-generics=yes will be required to optimize generics, the comment here is worth reading: rust-lang/rust#63484 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants