Skip to content
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

Consider shrinking ECS IDs #4820

Open
james7132 opened this issue May 21, 2022 · 4 comments
Open

Consider shrinking ECS IDs #4820

james7132 opened this issue May 21, 2022 · 4 comments
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible 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?

Currently all of the ECS IDs (sans Entity) is backed with a usize, which might be bigger than it needs to be. It'll be difficult to find a use case that legitimately needs more than u32::MAX archetypes, tables, bundles or components, which means the upper 4 bytes on 64-bit machines effectively go unused.

For Components and Bundles, it may make sense to drop to u16, as most of these are determined at compile time, or are conservatively added via modding/scripting.

What solution would you like?

Shrink ArchetypeId, TableId, ArchetypeComponentId to u32.

Tentatively shrink ComponentId and BundleId to u16.

What alternative(s) have you considered?

Leaving them as is.

Additional context

As a good portion of the metadata storage for ECS is stored in SparseSets embedded in Archetypes and Tables, shrinking these IDs can shrink the size of these sets, keeping them hotter in caches, and thus reducing access overhead.

@james7132 james7132 added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels May 21, 2022
@bjorn3
Copy link
Contributor

bjorn3 commented May 21, 2022

Tentatively shrink ComponentId and BundleId to u16.

I don't think using 16bit would make anything faster. At least wasm and arm/aarch64 have most instructions operate on the full register width which is 32 or 64 bits.

@james7132 james7132 added A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times and removed S-Needs-Triage This issue needs to be labelled labels May 21, 2022
@james7132
Copy link
Member Author

Tentatively shrink ComponentId and BundleId to u16.

I don't think using 16bit would make anything faster. At least wasm and arm/aarch64 have most instructions operate on the full register width which is 32 or 64 bits.

The register may not change, but the layout in memory will. We'd be able to fit more of the SparseArray in cache at once, and more per cache-line. It'd also be much more bounded in size as well. Given that we do one of these lookups per component every time we initialize a Fetch, something we do every Query::get call, we could shave off quite a bit of overhead.

Though as always, probably best to measure first to see if the gains are worth the limitations.

@bjorn3
Copy link
Contributor

bjorn3 commented May 21, 2022

I think it is very likely large games will exceed either 65536 components or 65536 bundles or both.

@HackerFoo
Copy link
Contributor

This wasn't Bevy, but I recently generalized the graph node type used in Noumenal so that I could try switching from usize to u16 - doing so had no effect on performance, but reduced memory use by about 40%. u32 saved about 20%.

I recommend doing the same, and maybe select the type using a feature. Memory usage is important on mobile devices.

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-Feature A new feature, making something new possible 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.

3 participants