Skip to content

Opprotunistically use dense iteration when an archetype and its table are 1:1 #12381

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

Closed
james7132 opened this issue Mar 8, 2024 · 4 comments · Fixed by #14049
Closed

Opprotunistically use dense iteration when an archetype and its table are 1:1 #12381

james7132 opened this issue Mar 8, 2024 · 4 comments · Fixed by #14049
Labels
A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times

Comments

@james7132
Copy link
Member

What problem does this solve or what need does it fill?

We currently force sparse iteration if any of the target components in the data or filter part of a query is a sparse set component. This is suboptimal given the random access pattern forced by archetypal iteration.

If an archetype and its table have the same entity count, we should be able to assume that they target the same set of entities, which should make it safe to use dense iteration.

What solution would you like?

Extend all iteration methods to opportunistically use dense iteration if the fetched archetype and table have the same length.

What alternative(s) have you considered?

Leave it as is, this may notably complicate the safety story for query iteration.

Additional context

Related: #2144.

@james7132 james7132 added A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times labels Mar 8, 2024
@alice-i-cecile
Copy link
Member

If an archetype and its table have the same entity count

Isn't it possible for them to have the same entity count by coincidence?

@james7132
Copy link
Member Author

james7132 commented Mar 8, 2024

An archetype can only have one table mapped to it. If they have the same entity count, the archetype and table should map to the same entities. If we add a new sparse set component to any of those entities, we still write to the same table, but fragment the archetype instead, which would disable this opportunistic optimization.

@cBournhonesque
Copy link
Contributor

cBournhonesque commented Jun 27, 2024

Why is iterating through archetypes slower?
Are the entities in archetype.entities() not sorted in the same order as the table entities?

@re0312
Copy link
Contributor

re0312 commented Jun 27, 2024

Why is iterating through archetypes slower? Are the entities in archetype.entities() not sorted in the same order as the table entities?

yeah , assume we have two distinct archetypes, let's call them A and B:
Archetype A: [ TableComponent, SparseComponent ]
Archetype B: [ TableComponent ]

Both archetypes share the same table_id. When entities in Archetype B are despawned, could potentially disrupting the order of entities in Archetype A.
Furthermore, the archetype iteration retrieves every entity from archetype.entities(), which may hinder certain compiler optimizations.

github-merge-queue bot pushed a commit that referenced this issue Aug 2, 2024
# Objective
- currently, bevy employs sparse iteration if any of the target
components in the query are stored in a sparse set. it may lead to
increased cache misses in some cases, potentially impacting performance.
- partial fixes #12381 

## Solution

- use dense iteration when an archetype and its table have the same
entity count.
- to avoid introducing complicate unsafe noise, this pr only implement
for `for_each ` style iteration.
- added a benchmark to test performance for hybrid iteration.


## Performance


![image](https://github.com/bevyengine/bevy/assets/45868716/5cce13cf-6ff2-4861-9576-e75edc63bd46)

nearly 2x win in specific scenarios, and no performance degradation in
other test cases.

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Christian Hughes <[email protected]>
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-Performance A change motivated by improving speed, memory usage or compile times
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants