Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upTracking issue for stable SIMD in Rust #48556
Comments
alexcrichton
added
B-RFC-approved
T-libs
C-tracking-issue
labels
Feb 26, 2018
This comment has been minimized.
This comment has been minimized.
|
My one request for the bikeshed (which the current PR already does and may be obvious, but I'll write it down anyway): Please ensure they're not all in the same module as things like |
This comment has been minimized.
This comment has been minimized.
|
What will be the story for external LLVM? (lacking |
This comment has been minimized.
This comment has been minimized.
|
@scottmcm certainly! I'd imagine that if we ever stabilized Rust-related intrinsics they'd not go into the same module (they probably wouldn't even be platform-specific). @cuviper currently it's an unresolved question, so if it doesn't get fixed it means that using an external LLVM would basically mean that |
This comment has been minimized.
This comment has been minimized.
One option raised in the RFC thread (that I personally quite like) was stabilizing To be explicit, under that plan the rustdoc page for Modules
Functions
|
This comment has been minimized.
This comment has been minimized.
|
Another naming idea I've just had. Right now the feature detection macro is |
This comment has been minimized.
This comment has been minimized.
|
Why keep all the leading underscores for the intrinsics? Surely even if we keep the same names as what the vendors chose, we can still remove those signs, right? |
This comment has been minimized.
This comment has been minimized.
|
The point is to expose vendor APIs. The vendor APIs have underscores. Therefore, ours do too. |
This comment has been minimized.
This comment has been minimized.
|
It is debatable that those underscores are actually part of the name. They only have one because C has no modules and namespacing, AFAICT. |
This comment has been minimized.
This comment has been minimized.
|
I would be happy dropping the topic if it was discussed at length already, but I couldn't find any discussion specific to them leading underscores. |
This comment has been minimized.
This comment has been minimized.
|
@nox rust-lang-nursery/stdsimd#212 --- My comment above is basically a summary of that. I probably won't say much else on the topic. |
This comment has been minimized.
This comment has been minimized.
|
@nox, @BurntSushi Continuing the discussion from there... since it hasn't been mentioned before: Leading |
This comment has been minimized.
This comment has been minimized.
|
@nox @Centril the recurring theme of stabilizing SIMD in Rust is "it's not our job to make this nice". Any attempt made to make SIMD different than what the vendors define has ended with uncomfortable questions and intrinsics that end up being left out. To that end the driving force for SIMD intrinsics in Rust is to get anything compiling on stable. Crates like Overall, again, the goal is to not enable ergonomic SIMD in Rust right now, but any SIMD in Rust. Following exactly what the vendors say is the easiest way for us to guarantee that all Rust programs will always have access to vendor intrinsics. |
This comment has been minimized.
This comment has been minimized.
|
I agree that the leading underscores are a C artifact, not a vendor choice (the C standard reserves identifiers of this form, so that's what C compilers use for intrinsics). Removing them is neither "trying to make it nicer/more ergonomic" (it's really only a minor aesthetic difference) nor involves any per-intrinsic judgement calls. It's a dead simple mechanical translation for a difference in language rules, almost as much as |
This comment has been minimized.
This comment has been minimized.
|
@rkruppe do we have a rock solid guarantee that no vendor will ever in the future add the same name without underscores? |
This comment has been minimized.
This comment has been minimized.
Can't speak for CPU vendors, but the probability seems very very low. Why would they add an intrinsic where the difference is only an underscore..? Further, as Rust's influence grows, they might not do this simply because of Rust. |
This comment has been minimized.
This comment has been minimized.
|
A name like
All extremely unlikely. The first one seems like the only one that doesn't sound like science fiction to me, and if that happens we'd have other problems anyway (such intrinsics may use function overloading and other features Rust doesn't have). |
This comment has been minimized.
This comment has been minimized.
This. The whole point is that the underscore-leading names were chosen so as to specifically not clash with user-defined functions. Which means they should never be using non-underscore names. It's against well-established C conventions. Hence, we should just rename them to follow Rust conventions, with no real chance there will be any name clash in the future, providing the vendors stay sane and respect C conventions. |
This comment has been minimized.
This comment has been minimized.
|
@Centril "probability seems very very low" is what I would say as well, but we're talking about stability of functions in the standard library, so "low probability" won't cut it unfortunately. @rkruppe I definitely agree, yeah, but "extremely unlikely" to me says "follow the vendor spec to the letter and we can figure out ergonomics later". |
This comment has been minimized.
This comment has been minimized.
|
Another point worth mentioning for staying exactly to the upstream spec is that I believe it actually boosts learnability. You'll have instant familiarity with any SIMD/intrinsic code written in C, of which there's already quite a lot! If we stray from the beaten path then we'll have to have a section of the documentation which is very clear about defining the mappings between intrinsic names and what we actually expose in Rust. |
This comment has been minimized.
This comment has been minimized.
|
I don't think renaming (no leading underscore or any other alteration) is useful. This is simply not the goal and only introduces pain points. I cannot think of a reason other than "i like that more" to justify that. It only introduces the possibility to naming clashes and "very very unlikely" is not convincing because we can prevent this 100% by not doing it altogether. I think its the best choice to follow the vendor naming schema as close as possible and i think we should even break compatibility if we ever introduce an error in the "public API" without doing some renaming like |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton But as @rkruppe said, removing the leading underscore isn't about ergonomics, it's about not porting C defects to Rust blindly. |
This comment has been minimized.
This comment has been minimized.
|
Sorry for the double post, but I also want to add that arguing that a vendor may release an unprefixed intrinsic with the same name as a prefixed one is to me as hypothetical as arguing that |
This comment has been minimized.
This comment has been minimized.
|
@nox but why stop by the |
This comment has been minimized.
This comment has been minimized.
|
@pythoneer Because the name is what the vendor decided, with a leading underscore because of nondescript limitations of C. |
This comment has been minimized.
This comment has been minimized.
|
@nox and the explicit goal of stdsimd is to expose this (however defect) vendor defined interface. |
This comment has been minimized.
This comment has been minimized.
Interface, sure, but not necessarily the naming conventions! |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 4, 2018
This comment has been minimized.
This comment has been minimized.
|
Will it be possible to migrate to something like |
This comment has been minimized.
This comment has been minimized.
|
Is |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 5, 2018
This comment has been minimized.
This comment has been minimized.
|
@Zoxc you may wish to comment on #42515, the issue dedicated to that. @newpavlov at this point I think it's a bit late to hold up stabilization of SIMD on a pre-RFC, but if that ends up being stabilized we can always rename via deprecation. |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 5, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 5, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 7, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 9, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 12, 2018
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Apr 13, 2018
|
The final comment period is now complete. |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 13, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 13, 2018
bors
added a commit
that referenced
this issue
Apr 14, 2018
bors
added a commit
that referenced
this issue
Apr 15, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Apr 16, 2018
bors
added a commit
that referenced
this issue
Apr 16, 2018
bors
added a commit
that referenced
this issue
Apr 17, 2018
bors
closed this
in
#49664
Apr 17, 2018
This comment has been minimized.
This comment has been minimized.
|
I don't know if it's too late to still tune things here, but the original RFC had two features that were changed during the discussion over there:
The RFC was accepted before those changes were made. The changes were made in the RFC at the end of February, implemented at the beginning of March, and the FCP went through mid April. Right now we have ~2 month of experience with these changes In any case, going through the RFC, I cannot pin point any concrete argument about why:
In particular, These last-minute changes make it more painful than necessary to write code even for #[target_feature(enabled = "sse3")]
unsafe fn foo() {
#[cfg(target_feature = "x86")] use core::arch::x86::*;
#[cfg(target_feature = "x86_64")] use core::arch::x86_64::*;
/* ... */
}all over the place, or at the top level, to avoid having to do this all over the place. Things don't get better when targeting multiple architectures. What before was horrible: #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), target_feature(enable = "sse4.2"))]
#[cfg_attr(any(target_arch = "arm", target_arch = "aarch64"), target_feature(enable = "neon"))]
unsafe foo() {
use core::arch::*;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
if is_feature_detected!("avx2") { ... } else { ... }
}
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] {
if is_feature_detected!("crypto") { ... } else { ... }
}
}now is worse: #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), target_feature(enable = "sse4.2"))]
#[cfg_attr(any(target_arch = "arm", target_arch = "aarch64"), target_feature(enable = "neon"))]
unsafe foo() {
#[cfg(target_arch = "x86")] use core::arch::x86::*;
#[cfg(target_arch = "x86_64")] use core::arch::x86_64::*
#[cfg(target_arch = "arm")] use core::arch::arm::*;
#[cfg(target_arch = "aarch64")] use core::arch::aarch64::*;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
if is_x86_feature_detected!("crypto") { ... } else { ... }
}
#[cfg(target_arch = "arm")] {
if is_arm_feature_detected!("crypto") { ... } else { ... }
}
#[cfg(target_arch = "aarch64")] {
if is_aarch64_feature_detected!("crypto") { ... } else { ... }
}
}This is particularly worrying if we want to add new "feature sets" for ergonomics like #[target_feature(enable = "simd128")]
unsafe foo() {
use core::arch::*;
if is_feature_detected!("crypto") { ... } else { ... }
}I remember that to me they sounded like a potentially good idea back then, so I did not gave them more thought (I was more in the "I want SIMD now" mood). But now that the love story has faded and I've had the chance to use them a couple of times, I've clashed against them every single time:
Anyways, can somebody summarize why doing those two changes were a good idea? In particular for the first change of putting the intrinsics in #[cfg(target_arch = "arm")]
#[target_feature(enable = "simd128")]
unsafe fn bar() { ... }
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "simd128")]
unsafe fn bar() { ... }
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "simd128")]
unsafe fn bar() { ... }
fn foo() {
if is_feature_detected("simd128") { bar() } else { fallback() }
}and the named macros wouldn't allow that. There are two ways of fixing this in a backwards compatible way:
So I don't think we should block landing this on these ergonomic issues. In any case, I don't feel I understand the real reasons behind the change, so maybe adding these conveniences defeats their purpose. cc @alexcrichton @rkruppe @eddyb @hsivonen @BurntSushi @Ericson2314 (those who had opinions about this in the RFC) |
This comment has been minimized.
This comment has been minimized.
|
@gnzlbg this was something I forgot about in the original RFC personally. In the standard library anything that isn't portable currently stylistically requires the "non portable part of it" to appear in the path you The name of the macro was the same rationale, ensuring that you aren't tricked to thinking it can be invoked in a portable context but rather explicitly specifying that it's not portable. |
This comment has been minimized.
This comment has been minimized.
Is this something that will be covered with the new portability lint? Also, by that rationale, should everything in |
This comment has been minimized.
This comment has been minimized.
|
@parched ideally, yes! If that exists we could perhaps consider moving everything wholesale to different modules. |
This comment has been minimized.
This comment has been minimized.
For |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
So should we do the changes? (add |
This comment has been minimized.
This comment has been minimized.
|
Er sorry I misread, I think. I do not think we should change anything. Perhaps one day intrinsic can live directly in |
alexcrichton commentedFeb 26, 2018
•
edited
This is a tracking issue for RFC 2325, adding SIMD support to stable Rust. There's a number of components here, including:
#[target_feature(enable = ...)]#[cfg(target_feature = ...)]is_target_feature_detected!macrostd::archnaming and submodulesThe initial implementation of this is being added in #48513 and the next steps would be:
Known issues
is_target_feature_detected!takes different arguments that#[target_feature]