Skip to content

Separate component and resource access #14561

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

Merged
merged 6 commits into from
Aug 6, 2024

Conversation

cBournhonesque
Copy link
Contributor

@cBournhonesque cBournhonesque commented Jul 31, 2024

Objective

Solution

  • Update access to have component fields and resource fields

Testing

  • Added some unit tests

@cBournhonesque cBournhonesque changed the title Cb/resource access Separate component and resource access Jul 31, 2024
@cBournhonesque cBournhonesque added A-ECS Entities, components, systems, and events D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels Jul 31, 2024
@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior C-Code-Quality A section of code that is hard to understand or change S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jul 31, 2024
@alice-i-cecile alice-i-cecile added this to the 0.15 milestone Jul 31, 2024
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my preferred approach. This is a straightforward and more correct model.

Code is good, tests are nice. There's a couple of docs that you missed updating but this is fundamentally an approval.

/// The exclusively-accessed components.
component_writes: FixedBitSet,
/// All accessed resources.
resource_read_and_writes: FixedBitSet,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why introduce extra FixedBitSets for resources here? IMO, we only need to split 'reads/writes_all' into 'read/write_all_component/resource' because Components and Resources share ID space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's to check the has_any_resource that is needed to check compatibility

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also a correctness hazard in sharing the bit sets for resources and components. There's a risk that the component Foo clashes with the resource Foo, for types which are both components and resources. This isn't the right memory model, and care must be taken far elsewhere in the stack (when assigning component ids) to avoid it if we don't separate it here.

A test to validate that behavior would be nice actually.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but we should discuss whether to split the ID space. With this PR each bitset is going to be oversized and do extra work for the id's of the other type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what I am most worried about is that Access is used in many places (such as EntityFilterRef), Perhaps we can move it to a new struct CombinedAccess and used it for' FilteredAccessSet::combined_access, with hhis way, we can limit the influence of this pr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but we should discuss whether to split the ID space. With this PR each bitset is going to be oversized and do extra work for the id's of the other type.

Note that this probably won't be a problem anymore if we go ahead with this
#14385
which removes the bitsets.
(which will probably be necessary since with relations the ComponentIds will become very high, so the memory used by FixedBitSet will become prohibitive)

what I am most worried about is that Access is used in many places (such as EntityFilterRef), Perhaps we can move it to a new struct CombinedAccess and used it for' FilteredAccessSet::combined_access, with hhis way, we can limit the influence of this pr.

Your concern is the increased memory usage because of 2 FixedBitSets?
Yes i think the solution would probably be #14385

Copy link
Contributor

@re0312 re0312 Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your concern is the increased memory usage because of 2 FixedBitSets?

yeah ,Two FixedBitSets (even not used) occupy extra 48 bytes, we only use it for combined access,
With #14385, this number is even Larger

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A test to validate that behavior would be nice actually.

@alice-i-cecile added a test that checks that a resource/component that share the same componentId (same struct) do not conflict with each other

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah ,Two FixedBitSets (even not used) occupy extra 48 bytes, we only use it for combined access,
With #14385, this number is even Larger

On the contrary with #14385 we don't have a problem anymore, no?
14385 uses a Vec<usize> for the access; so if there are no resource accessed we would just have an empty vec.

Or do you mean stack usage and not heap usage?

Copy link
Contributor

@re0312 re0312 Aug 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with #14385 It will make the problem more serious.

  1. Access is just a struct, whether it occupies stack or heap depends on how you use it
  2. Update Access and FilteredAccess to use sorted vecs instead of FixedBitSet #14385 uses SmallVec<[usize;N> (N default to 64),so it occupies 24+8 * 64 =536 bytes (* 2 = 1072 bytes ) even without any usage.

Copy link
Contributor

@Olle-Lukowski Olle-Lukowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good changes, and always good to add some test cases!

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Aug 2, 2024
@alice-i-cecile
Copy link
Member

I want to merge #14579 first, to ensure that we have more test cases in place.

@alice-i-cecile
Copy link
Member

alice-i-cecile commented Aug 2, 2024

@re0312 while I share your nervousness about performance, the existing model is both wrong and confusing IMO. The test added in daf6981 won't pass using the access model on main. We should ensure correctness first, then evaluate techniques to improve memory usage and other performance-related elements.

@re0312
Copy link
Contributor

re0312 commented Aug 2, 2024

@re0312 while I share your nervousness about performance, the existing model is both wrong and confusing IMO. The test added in daf6981 won't pass using the access model on main. We should ensure correctness first, then evaluate techniques to improve memory usage and other performance-related elements.

yeah. totally agree with you , I don't intend to block this , I'm merely expressing my concern about it. Access is still used in many performance-sensitive places (such as dynamic query iteration, where an Access::clone is performed on each matched entity ).
but I don't object to left performance optimization to later pr.

@alice-i-cecile alice-i-cecile added the X-Contentious There are nontrivial implications that should be thought through label Aug 6, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Aug 6, 2024
Merged via the queue into bevyengine:main with commit 3a664b0 Aug 6, 2024
28 checks passed
github-merge-queue bot pushed a commit that referenced this pull request Nov 6, 2024
# Objective

Re-enable some tests in `entity_ref.rs` that are marked as `#[ignore]`,
but that pass after #14561.

## Solution

Remove `#[ignore]` from those tests.
ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Dec 2, 2024
# Objective

Re-enable some tests in `entity_ref.rs` that are marked as `#[ignore]`,
but that pass after bevyengine#14561.

## Solution

Remove `#[ignore]` from those tests.
ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Jan 6, 2025
# Objective

Re-enable some tests in `entity_ref.rs` that are marked as `#[ignore]`,
but that pass after bevyengine#14561.

## Solution

Remove `#[ignore]` from those tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior C-Code-Quality A section of code that is hard to understand or change D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
5 participants