-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Target feature runtime #2725
base: master
Are you sure you want to change the base?
Target feature runtime #2725
Conversation
SSE3. In Rust, we call `x86_64` the target architecture "family", and extensions | ||
like SSE2 or SSE3 "target-features". | ||
|
||
Many Rust applications compiled for `x86_64-unknonw-linux-gnu` do want to use |
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.
Many Rust applications compiled for `x86_64-unknonw-linux-gnu` do want to use | |
Many Rust applications compiled for `x86_64-unknown-linux-gnu` do want to use |
* Should the `libstd` run-time be overridable? For example, by only providing it | ||
if no other crate in the dependency graph provides a runtime ? This would be a | ||
forward-compatible extension, but no use case considered requires it. | ||
|
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.
- Does
core::detect::is_target_feature_detected
cache the result ofcore::detect::TargetFeatureRuntime::is_feature_detected
or is the later responsible for caching itself?
The later is responsible for caching. This allows the runtime to control
everything.
Caching often requires making decisions about how to cache, eg using a
global relaxed atomic bitset, a mutex, thread locals, etc. There is no one
size fits all for no_std binaries.
|
Sounds good to me. One thing I couldn't quite find in the RFC is how this actually bridges between runtime and compile-time detection, i.e. how the macro in And regarding the feature detection, is everyone supposed to roll their own or is there going to be a good default implementation like for the panic handling and |
The macros already do that, e.g., the
This is already the case even if you use compile-time feature detection via If you want to make sure that no run-time detection actually ever happens, you could implement your own run-time that just calls panics, e.g., by calling
I'm not sure if this will answer your question, but the macros are only available for targets that support them. If a target does not support them, there is no macro for users to use, so what you describe cannot currently happen. That is, if you want to use
Currently, the |
That seems like a bad idea. People not being able to use We do see a lot of such problems in
It would be way more convenient if that was implicit (or at least there's a separate version with implicit feature gates). Requiring to manually pair those seems like a perfect way to cause seemingly random build errors and wrong code paths being used. Done properly this would also eliminate my concern above... |
The runtime target-feature detection macros currently only allow detecting features for which this cannot happen.
This RFC does not require doing that. |
@therealprof this RFC only proposes allowing users to configure the run-time component of the target-feature detection system. That system has already been RFC'ed, and is implemented on both stable and nightly for half a dozen targets (including embedded ones) and dozens of target features. This RFC does not change anything about how any of that currently works. That is out-of-scope. If you have questions about that system, the docs are usually a good place to start, but you can also go through the RFCs (e.g. the std::arch RFC or the target-feature RFC). |
It's okay, I was reading a bit more into the preamble than this RFC is about. It's still a useful proposal, just not as useful for me as I'd had hoped from my initial reading. 😉 |
It might be out-of-scope/offtopic for this RFC, but would it be possible for you to open an issue in this repo about which problem you need to solve ? We can try to figure out how to do that there. |
requires executing privileged CPU instructions that are illegal to execute | ||
from user-space code. User-space applications query the available | ||
target-feature set from the operating system. Often, they might also want to | ||
cache the result to avoid repeating system calls. |
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.
@lu-zero also mentioned another use-case here: they want to control feature detection at run-time via, e.g., environment variables.
I can imagine that one use case of this would be, for example, to disable AVX-512 usage via such an environment variable, but maybe they can comment here on what they have in mind.
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.
Exactly, the idea is to disable features the cpu supports (or seems to support) at runtime. It is useful for debugging or to work around hardware bugs.
Overall I think this RFC would be very helpful for embedded targets. As written it does not impose any cost on the targets that they do not opt in.
If the target feature runtime API would be stringly typed and pattern match on string literals, then any implementation of it would include these literals in
I think libcore could provide a cache as a building block rather than something fixed with mutable state. This cache could look like a struct generic over target feature runtimes, like
I think almost every case where a cache is used should work just fine with atomics. By making this cache a building block, it is easy to convert it to a thread-local one: add a wrapper that allocates the cache as a thread local, then delegate to it. Similarly, it can be reset by reinitializing. In the cases where features should not be cached at all (for example, in a system that frequently migrates threads between cores with different feature sets--sometimes with irritating consequences), it can be omitted. The one case not covered by my proposal is targets without atomics. I think targets without atomics that are currently supported lack any runtime features anyway (since those tend to be the absolute smallest cores like Cortex-M0), so there's no real downside. If it turns out that a cache is useful for those targets, then we could later expose it on such targets under a different name and without atomics, with the caller responsible for synchronization.
This RFC would have fit into the "embedded productivity" part of the 2019 roadmap. I'm not sure about the 2020 roadmap, but so far it sounds like "finish what we started in 2019" would be a large aspect of it, so it probably fits there, too. |
I'm against adding yet another "global functionality" attribute like |
@rust-lang/lang discussed this today. Consensus:
|
What should we do to progress on this issue? |
Rendered
This RFC proposes exporting the target-feature detection macros (e.g.
is_x86_feature_detected!
) fromlibcore
, enabling all Rust libraries, including#![no_std]
libraries, to use them. It works out the details of the implementation, and propose to make parts of it public to allow#![no_std]
binaries andlibstd
to provide their own target-feature-detection run-times via these APIs.This RFC can be stabilized in stages. We can stabilize the exporting of the target-feature detection macros from libcore without stabilizing anything else, since the standard library and
#![no_std]
libraries can both use unstable Rust features. Once we start working on the stabilization of#![no_std]
binaries, we can revisit the stabilization of these APIs.