-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Contiguous access #21984
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
Contiguous access #21984
Conversation
|
This pr just enables slices from tables to be returned directly when applicable, it doesn't implement any batches and it doesn't ensure any specific (other than rust's) alignment (yet these slices may be used to apply simd).
This pr doesn't deal with any alignments but (as of my understanding) you can always take sub-slices which would meet your alignment requirements. And just referring to the issue #21861, even without any specific alignment the code gets vectorized.
No, the returned slices do not have any specific (other than rust's) alignment requirements. |
|
The solution looks promising to solve issue #21861. If you want to use SIMD instructions explicitly, alignment is something you usually have to manage yourself (with an aligned allocator or a peeled prologue). Auto-vectorization won’t “update” the alignment for you – it just uses whatever alignment it can prove and otherwise emits unaligned loads. From that perspective, a contiguous slice is already sufficient; fully aligned SIMD is a separate concern on top of that. |
hymm
left a comment
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.
This is not a full review, but onboard with the general approach in this pr. Overall this is fairly straightforward. I imagine we'll eventually want to have some simd aligned storage, but in the meantime users can probably align their components manually.
|
You added a new example but didn't add metadata for it. Please update the root Cargo.toml file. |
hymm
left a comment
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.
The recent changes fixed my reservations with this pr. Just some nits left.
chescock
left a comment
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.
This looks good! My comments are mostly just thoughts on more polish for the Contiguous(Ref|Mut) types, and shouldn't block this PR.
|
|
||
| /// Data type returned by [`ContiguousQueryData::fetch_contiguous`](crate::query::ContiguousQueryData::fetch_contiguous) for [`Ref<T>`]. | ||
| #[derive(Clone)] | ||
| pub struct ContiguousRef<'w, T> { |
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.
Is there a pub way to construct these? I bet someone will ask for one to be added later, but I think it's reasonable to leave it out until someone does.
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.
See ContiguousRef::new
|
|
||
| /// Data type returned by [`ContiguousQueryData::fetch_contiguous`](crate::query::ContiguousQueryData::fetch_contiguous) for [`Ref<T>`]. | ||
| #[derive(Clone)] | ||
| pub struct ContiguousRef<'w, T> { |
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.
Would it make sense to impl Deref<Target = [T]> for ContiguousRef and ContiguousMut?
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.
Implemented Deref<Target = [T]>, DerefMut<Target = [T]>, AsRef<[T]>, AsMut<[T]> and IntoIterator<Item = &T|&mut T> for ContiguousRef and ContiguousMut. Traits returning mutable references also update change ticks automatically, added bypass_change_detection as well.
alice-i-cecile
left a comment
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.
I spent some time today understanding and reasoning through this. I'm very impressed, and think this is going to be a very useful feature. Merging.
Special thanks to the reviewers for the refinements here: your guidance here was excellent.
Objective
Enables accessing slices from tables directly via Queries.
Fixes: #21861
Solution
One new trait:
ContiguousQueryDataallows to fetch all values from tables all at once (an implementation for&Treturns a slice of components in the set table, for&mut Treturns a mutable slice of components in the set table as well as a struct with methods to set update ticks (to match thefetchimplementation))Methods
contiguous_iter,contiguous_iter_mutand similar inQueryandQueryStatemaking possible to iterate using these traits.Macro
QueryDatawas updated to support contiguous items whencontiguous(target)attribute is added (a target can beall,mutableandimmutable, refer to thecustom_query_paramexample)Testing
sparse_set_contiguous_querytest verifies that you can't usenext_contiguouswith sparse set componentstest_contiguous_query_datatest verifies that returned values are validbase_contiguousbenchmark (file is namediter_simple_contiguous.rs)base_no_detectionbenchmark (file is namediter_simple_no_detection.rs)base_no_detection_contiguousbenchmark (file is namediter_simple_no_detection_contiguous.rs)base_contiguous_avx2benchmark (file is namediter_simple_contiguous_avx2.rs)Showcase
Examples
contiguous_query,custom_query_paramExample
Benchmarks
Code for
basebenchmark:Iterating over 10000 entities from a single table and increasing a 3-dimensional vector from component
Positionby a 3-dimensional vector from componentVelocitybypass_change_detection()methodUsing contiguous 'iterator' makes the program a little bit faster and it can be further vectorized to make it even faster