rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.82k stars 12.66k forks source link

Tracking issue for RFC 2412, "The optimize attribute" #54882

Open Centril opened 6 years ago

Centril commented 6 years ago

This is a tracking issue for the RFC "The optimize attribute" (rust-lang/rfcs#2412).

Steps:

Unresolved questions:

Centril commented 6 years ago

@nagisa I've added all unresolved questions from the RFC for completeness; the first 2 may already be resolved, if you feel that's the case; tick the boxes.

nagisa commented 6 years ago
  • Should we also implement optimize(always)? optimize(level=x)?
    • Left for future discussion, but should make sure such extension is possible.

Marking as resolved just because these never came up during the RFC discussion, especially since the attribute design does not prohibit adding these as a feature later on.


I’m assigning myself for now as I intend to implement this. Failing to dedicate time for this within two or so weeks I pledge to write up some instructions.

nagisa commented 6 years ago

I’ve implementation for optimize(size) now and am looking into ways to implement the harder side – optimize(speed). I might end up splitting the work into two PRs depending on how things go.

Eh2406 commented 5 years ago

Would this allow a crate (proptest, quickcheck) that is performance sensitive, but often used in debug builds, to specify that it should always be built with release?

nagisa commented 5 years ago

The implementation for optimize(size) and optimize(speed) has now landed. Currently RFC is not fully implemented as the attribute propagation mechanic specified in the RFC is missing from the implementation. Nevertheless the actual functionality is present and can be toyed with.

Another thing that I’ve realised just now is that I never tested and is implemented incorrectly currently is "unused_attribute". The lint does not fire for the attribute applied to non-function items. This should also be fixed before any sort of stabilisation can proceed.

My recent observation is that optimize(none) is fairly often used by people to debug functions in an otherwise optimized build. It may be sensible to add it as well at some point.

Centril commented 5 years ago

@nagisa Any updates re. the remaining work?

Jasper-Bekkers commented 4 years ago

My recent observation is that optimize(none) is fairly often used by people to debug functions in an otherwise optimized build. It may be sensible to add it as well at some point.

+1 For this, in C++ code bases I've worked on this was very useful in a few cases;

I'd love to see the optimize(none) attribute for working with large code-bases.

steveklabnik commented 4 years ago

Triage: not aware of any movements here lately.

dmitry-zakablukov commented 3 years ago

optimize(none) will be very useful for code virtualization with VmProtect, for example. It is known that optimized functions are very hard to virtualize, because they can have unexpected returns within, can be inlined, can include inlined code. All of this may lead to faulty code after virtualization or to failure of virtualization itself. One way to solve this problem is to simplify a code. But very often this is not that easy to do or may be even impossible to do. The other way is to disable code optimization for a single function that will be virtualized. And for now this is can't be done even with nightly rust compiler.

So please, add support of optimize(none)!

hydra commented 3 years ago

Would just like to add my two cents to this:

After working on many embedded projects on processors with limited storage space it was critical to be able to change the optimization levels, here's some use-cases:

obsgolem commented 2 years ago

Just wanted to hop in to agree that optimize(none) is pretty important for debugging.

hydra commented 2 years ago

Another two cents:

Perhaps some options when building crates like 'ignore optimize attribute', 'default', 'debug', 'release', 'size', 'speed', 'none' that can be applied per-dependency which overrides the default optimization level. e.g. you would likely set 'core' and 'std' to 'release', and perhaps a bugged workspace crate to 'debug' and build using '--release' so you can debug the bugged workspace crate and not have everything in the bugged workspace crate optimized away.

jgarvin commented 2 years ago

@hydra Cargo already let's you override the optimization level for dependencies, it's great: https://doc.rust-lang.org/nightly/cargo/reference/profiles.html#overrides

I use it for gamedev so that ggez/bevy/etc are built optimized but my game logic is debug. But per function control is much more surgical and a nice feature.

hydra commented 2 years ago

@hydra Cargo already let's you override the optimization level for dependencies, it's great: https://doc.rust-lang.org/nightly/cargo/reference/profiles.html#overrides

I use it for gamedev so that ggez/bevy/etc are built optimized but my game logic is debug. But per function control is much more surgical and a nice feature.

@jgarvin cool, i'll check that out. With regard to the per-module comment above I was sort of wanting something between a surgeon's knife (function attribute) and a spoon (dependency level) though. 😃

joshtriplett commented 2 years ago

In 2019 @nagisa mentioned that the propagation mechanism was not implemented. Is that still the case?

We discussed this in today's @rust-lang/lang meeting, and we're interested in getting this over the finish line.

We also do see the multiple people asking after optimize(none), and we'd be open to that, but we feel that that needs a follow-up RFC or MCP defining the exact expectations there, since different prospective users of that may have different needs. So we'd like to keep this tracking issue just for what was defined in RFC 2412.

nagisa commented 2 years ago

The propagation mechanism still hasn't been implemented and at this point I'm quite confident that it is going to be something we will want to have as a more general mechanism (e.g. this is desirable for attributes such as #[no_coverage] as well.)

My feeling is that we should actually remove the part about propagation from the RFC scope for this specific attribute and work on it separately, defining semantics for propagation that make sense in a broader context. (It might very well be the case that semantics specified in the #[optimize(...)] RFC are the right ones, but I don't think we should take any guesses there)

ppannuto commented 2 years ago

As one concrete use case for optimize(none): for Tock OS, many of our platforms are sufficiently space-constrained that we must always leave optimizations on in order to build kernel/application images which will fit on the board.

Unfortunately, this can make debugging somewhat challenging. We currently employ a mix of #[inline_never] and #[no_mangle] to help pinpoint troublesome functions, but being able to selectively disable optimizations in certain regions would be a huge debugging help for us. CC @gemarcano who ran into this particular hurdle earlier today, and was hoping for an optimize(none) directive.

hiroki-chen commented 1 year ago

Optimization prevention is also strongly related to security issues. To prevent timing side-channel attacks against some cryptographic algorithm implementations, we must ensure some operations are constant-time, i.e., their execution time should not depend on the secret input, if any. OpenSSL, libsodium and many other crypto libraries all implement constant-time functions like swap, sort, etc.

The memory safety and the strong guarantee of type safety provided by the Rust programming language make it a good candidate for implementing security-sensitive applications like blockchain, and zero-knowledge-proof systems. However, the lack of optimization control subtly undermines the robustness of these systems because Rust only has some sort of blackbox function core::hint::black_box() which prevents compiler optimizations in a best-effort way.

The subtle crate provides a best-effort way to implement constant-time crypto algorithms using black_box or read_volatile, but I still wonder if we can take a step further and have control over LLVM's behavior so that we can avoid the boilerplate of writing complex code (e.g., inline assemblies).

clubby789 commented 2 months ago

cc #128488 https://github.com/rust-lang/rust/pull/128581#discussion_r1702437305 The RFC specifies we should emit an unused_attributes warning when misapplied, but similar attributes emit an error instead.

the8472 commented 2 months ago

I have opened #129063 which will add some uses of #[optimize(size)] to std.

peter-lyons-kehl commented 2 months ago

For anyone wanting to try (on nightly):

Someone please update "Feature Name" at https://rust-lang.github.io/rfcs/2412-optimize-attr.html.