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

Fix double indirection when applying command queues #11822

Merged

Conversation

JoJoJet
Copy link
Member

@JoJoJet JoJoJet commented Feb 11, 2024

Objective

When applying a command, we currently use double indirection for the world reference &mut Option<&mut World>. Since this is used across a fn pointer boundary, this can't get optimized away.

Solution

Reborrow the world reference and pass Option<&mut World> instead.

@JoJoJet JoJoJet added A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times labels Feb 11, 2024
@alice-i-cecile alice-i-cecile added the C-Code-Quality A section of code that is hard to understand or change label Feb 11, 2024
@@ -157,7 +157,7 @@ impl CommandQueue {
// SAFETY: The data underneath the cursor must correspond to the type erased in metadata,
// since they were stored next to each other by `.push()`.
// For ZSTs, the type doesn't matter as long as the pointer is non-null.
let size = unsafe { (meta.consume_command_and_get_size)(cmd, &mut world) };
let size = unsafe { (meta.consume_command_and_get_size)(cmd, world.as_deref_mut()) };
Copy link
Member

@james7132 james7132 Feb 11, 2024

Choose a reason for hiding this comment

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

Great catch on this, though I wonder if the compiler will lift the branch out of the loop. Either way, I don't think this is the bottleneck when it comes to command application given what commands typically entail, so probably not a blocker.

Copy link
Member

Choose a reason for hiding this comment

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

This seems to remove two mov instructions from outside of the hot loop: james7132/bevy_asm_tests@main...remove-double-deref#diff-8e36b64d5c51682bb463a51ec6e670b2ec99545945bc4753f4e77ef274c5faa0L27. This likely has a stronger impact inside of the commands themselves.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think this introduces a branch -- as_deref_mut() should be a no-op here

Copy link
Member Author

Choose a reason for hiding this comment

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

I bet the moves getting removed are due to the fact that the compiler no longer has to deal with the possibility of a command swapping the world from None to Some or vice versa.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Feb 12, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Feb 12, 2024
Merged via the queue into bevyengine:main with commit bd25135 Feb 12, 2024
28 checks passed
@JoJoJet JoJoJet deleted the command-queue-double-indirection branch March 15, 2024 23:50
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-Code-Quality A section of code that is hard to understand or change C-Performance A change motivated by improving speed, memory usage or compile times S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants