-
Notifications
You must be signed in to change notification settings - Fork 48
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
Portable SIMD project group #29
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed. |
Hey @rust-lang/lang -- we haven't seen anyone volunteering to serve as liaison for this project. If we're not able to find a liaison in the next week or so, I'm going to close the issue. If you think you might like to serve as a liaison, even if you don't have bandwidth right now, please do speak up -- we can always put the proposal on the "deferred list" to pick up when we have time. |
We discussed this in our @rust-lang/lang meeting today. We went back and forth about where it fit into our priorities and so forth, but one of the final conclusions we came to was that it seemed like this was very much a "library design" question more than anything. The "language design" portion of it is basically limited to "should we add intrinsic capabilities and therefore tie ourselves to LLVM even further", correct? We'd be curious therefore to hear from some @rust-lang/libs folk as to whether there is appetite to pursue this design. One of the other questions that we wanted input on was whether there are other crates who have pursued exposing portable SIMD in the library space beyond Some other notes from the minutes:
|
I don't think that, from a formal specification perspective, this is true. Another rust implementation could provide a fully semantically-correct implementation by just calling the scalar versions of all the functions in the appropriate loops. Now, obviously from a quality-of-implementation perspective a compiler would likely want to provide something smarter than that, to take better advantage of hardware capabilities. But I think LLVM is only one way of getting that -- albeit what I would probably pick if I was implementing atop of it anyway. We could also have it with an implementation strategy of My expectation from "portable" is that such differences would necessarily be inobservable semantically, and thus I think I personally would be fine with this being entirely a libs projects: to figure out the portable set of operations, how best to expose a rust interface to those, and how best to have them interop with non-portable platform intrinsics where needed, etc. (There might be some libs-impl/compiler/lang conversations about implementations details, but I suspect none of those will lock us into things.) |
Just stop deliberately blocking regular users from linking to LLVM intrinsics (if that's what they want to do), and then none of this needs to be in the standard library at all. Any crate could just make any design, and if it turns out bad then people can migrate to some other design. And if a specific design is some day determined to be good enough, it can become part of the standard library then. EDIT: There are a few other blockers to people doing their own out-of-stdlib experimentation, besides just linking to llvm intrinsics, but not too many. |
I think "C parity" mischaracterizes this:
I think exposing the intrinsics that would allow |
Also, I don't see this as a particularly "embedded" thing: E.g. my use cases for this involve desktop and mobile. (Apple Silicon is going to make this even more relevant on desktop than it already is.) |
Discussed in the rust-lang/lang meeting:
|
Right now we haven't fleshed out our project group process for libs (I'm writing up an RFC for catching up with the governance of other teams right now). In the meantime @hsivonen if you don't want to be blocked getting the ball rolling establishing a group, which I'd be on-board with, we could follow the same RFC process the Error handling group has. |
Ah I should’ve followed up here, but we turned this proposal into an RFC for libs here: rust-lang/rfcs#2977 |
WARNING
The Major Change Process was proposed in RFC 2936 and is not yet in
full operation. This template is meant to show how it could work.
Proposal
Create a project group for considering what portable SIMD in the standard library should look like.
Motivation, use-cases, and solution sketches
While Rust presently exposes ALU features of the underlying ISAs in a portable way, it doesn't expose SIMD capabilities in a portable way except for autovectorization.
A wide variety of computation tasks can be accomplished faster using SIMD than using the ALU capabilities. Relying on autovectorization to go from ALU-oriented source code to SIMD-using object code is not a proper programming model. It is brittle and depends on the programmer being able to guess correctly what the compiler back end will do. Requiring godbolting for every step is not good for programmer productivity.
Using ISA-specific instructions results in ISA-specific code. For things like "perform lane-wise addition these two vectors of 16
u8
lanes" should be a portable operation for the same reason as "add these twou8
scalars" is a portable operation that does not require the programmer to write ISA-specific code.Typical use cases for SIMD involve text encoding conversion and graphics operations on bitmaps. Firefox already relies of the Rust
packed_simd
crate for text encoding conversion.Compiler back ends in general and LLVM in particular provide a notion of portable SIMD where the types are lane-aware and of particular size and the operations are ISA-independent and lower to ISA-specific instructions later. To avoid a massive task of replicating the capabilities of LLVM's optimizer and back ends, it makes sense to leverage this existing capability.
However, to avoid exposing the potentially subject-to-change LLVM intrinsics, it makes sense expose an API that is conceptually close and maps rather directly to the LLVM concepts while making sense for Rust and being stable for Rust applications. This means introducing lane-aware types of typical vector sizes, such as
u8x16
,i16x8
,f32x4
, etc., and providing lane-wise operations that are broadly supported by various ISAs on these types. This means basic lane-wise arithmetic and comparisons.Additionally, it is essential to provide shuffles where what lane goes where is known at compile time. Also, unlike the LLVM layer, it makes sense to provide distinct boolean/mask vector types for the outputs of lanewise comparisons, because encoding the invariant that all bits of a lane are either one or zero allows operations like "are all lanes true" or "is at least one lane true" to be implemented more efficiently especially on x86/x86_64.
When the target doesn't support SIMD, LLVM provides ALU-based emulation, which might not be a performance win compared to manual ALU code, but at least keeps the code portable.
When the target does support SIMD, the portable types must be zero-cost transmutable to the types that vendor intrinsics accept, so that specific things can be optimized with ISA-specific alternative code paths.
The
packed_simd
crate provides an implementation that already works across a wide variety of Rust targets and that has already been developed with the intent that it could becomestd::simd
. It makes sense not to start from scratch but to start from there.The code needs to go in the standard library if it is assumed that rustc won't, on stable Rust, expose the kind of compiler internals that
packed_simd
depends on.Please see the FAQ.
Links and related work
packed_simd
cratepacked_simd
has stalledsimd
crateThe Major Change Process
Once this MCP is filed, a Zulip topic will be opened for discussion. Ultimately, one of the following things can happen:
You can read [more about the lang-team MCP process on forge].
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
The text was updated successfully, but these errors were encountered: