Repository navigation
Specify EntityLocation alignment to improve codegen - #26042
Merged
alice-i-cecile merged 2 commits intoOct 7, 2026
Merged
alice-i-cecile merged 2 commits into
alice-i-cecile merged 2 commits into
Conversation
alice-i-cecile
approved these changes
Oct 6, 2026
hymm
approved these changes
Oct 6, 2026
hymm
left a comment
Contributor
There was a problem hiding this comment.
This looks like it was a fun hole to jump down.
alice-i-cecile
enabled auto-merge
October 6, 2026 22:27
alice-i-cecile
disabled auto-merge
October 7, 2026 19:17
alice-i-cecile
enabled auto-merge
October 7, 2026 19:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
Fixes #25839.
Solution
#25632 changed the memory layout of
UnsafeEntityCell, which caused some codegen downstream to hit a store-to-load forwarding failure. (I hadn't heard about those before working on this PR, this blogpost has a nice explainer. TLDR is that it's slow).Adding a
repr(align(8))toEntityLocationseems to tip LLVM codegen the right way and we get to avoid that store-to-load forwarding failure, which lets us recover the pre-#25632 performance.The PR also speeds up
World::entity, which already had a similar forwarding failure before #25632.I want all the details!
EntityLocationgets loaded from the entity table into three registers:archetype_row(4 bytes),table_row+archetype_id(8 bytes), andtable_id(4 bytes). Since #25632, it then gets written as 8+4+4 intoUnsafeEntityCell:archetype_row+table_row, thenarchetype_id, thentable_id. That first 8-byte chunk needsarchetype_rowplus the half of the second register, and LLVM builds it by writing both registers to the stack and reading 8 bytes back. That read spans two pending stores and causes the store-to-load forwarding to fail. This path gets hit in most places where we build anUnsafeEntityCellfrom a location, and so ends up affecting multiple benchmarks.Putting a
repr(align(8))ontoEntityLocationmakes LLVM load it asarchetype_row,table_row, andarchetype_id+table_id(4+4+8), and it can then joinarchetype_rowandtable_rowdirectly in a register without the round-trip to the stack.Testing
Ran the benchmarks mentioned in #25839.
We get a bunch of nice improvements, with
observe/observer_custom/10000_entitybeing the only one that's still worse than before #25632. Not sure what's going on there, and will probably leave it as future work.world_entity/50000_entitiesevent_propagation/four_event_typesobserve/observer_custom/10000_entityecs::resources::insert_removedespawn_world_recursive/1_entitiesdespawn_world_recursive/100_entitiesdespawn_world_recursive/10000_entitiesquery_get_many_2/50000_calls_tablequery_get_many_2/50000_calls_sparsequery_get_many_5/50000_calls_tablequery_get_many_5/50000_calls_sparsequery_get_many_10/50000_calls_tablequery_get_many_10/50000_calls_sparseget_entity_mut_slice/size/20get_entity_mut_slice/size/200get_entity_mut_slice/size/2000I started by pointing a LLM at the issue and asked it to inspect the assembly before and after a716a99 to try and find a cause. It directed me towards the store-to-load issue. I'd never heard of that so I did a bunch of reading to understand what was going on, then spent way too much time staring at the assembly, and finally ran the benchmarks.