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

[Merged by Bors] - Skip drop when needs_drop is false #4773

Closed
wants to merge 4 commits into from

Conversation

DJMcNab
Copy link
Member

@DJMcNab DJMcNab commented May 16, 2022

Objective

  • We do a lot of function pointer calls in a hot loop (clearing entities in render). This is slow, since calling function pointers cannot be optimised out. We can avoid that in the cases where the function call is a no-op.
  • Alternative to Optimize dropping in bevy_ecs #2897
  • On my machine, in many_cubes, this reduces dropping time from ~150μs to ~80μs.

Solution

  • Make drop in BlobVec an Option, recording whether the given drop impl is required or not.
  • Note that this does add branching in some cases - we could consider splitting this into two fields, i.e. unconditionally call the drop fn pointer.
  • My intuition of how often types stored in World should have non-trivial drops makes me think that would be slower, however.

N.B. Even once this lands, we should still test having a 'drop_multiple' variant - for types with a real Drop impl, the current implementation is definitely optimal.

@DJMcNab DJMcNab added C-Enhancement A new feature A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times labels May 16, 2022
crates/bevy_ecs/src/component.rs Show resolved Hide resolved
crates/bevy_render/src/lib.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Show resolved Hide resolved
}
{
#[cfg(feature = "trace")]
let _stage_span =
Copy link
Member Author

Choose a reason for hiding this comment

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

@bjorn3 I've left this in for now, as I'm struggling to find a compelling argument for running Cleanup and clearing the entities to have no differentiation. Perhaps it should be nested, but that's a different question to what you were requesting.

Copy link
Member

@james7132 james7132 left a comment

Choose a reason for hiding this comment

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

LGTM other than the existing review comments. I was a bit suspicious of adding a branch in the hotpath for deleting/moving entities around, but it makes sense that a branch would be preferable to what is effectively a virtual function call that POD components don't use.

@james7132 james7132 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 May 16, 2022
crates/bevy_ecs/src/component.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/component.rs Outdated Show resolved Hide resolved
DJMcNab and others added 2 commits May 16, 2022 21:59
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request May 17, 2022
# Objective

- We do a lot of function pointer calls in a hot loop (clearing entities in render). This is slow, since calling function pointers cannot be optimised out. We can avoid that in the cases where the function call is a no-op.
- Alternative to #2897
- On my machine, in `many_cubes`, this reduces dropping time from ~150μs to ~80μs.

## Solution
-  Make `drop` in `BlobVec` an `Option`, recording whether the given drop impl is required or not.
- Note that this does add branching in some cases - we could consider splitting this into two fields, i.e. unconditionally call the `drop` fn pointer.
- My intuition of how often types stored in `World` should have non-trivial drops makes me think that would be slower, however. 

N.B. Even once this lands, we should still test having a 'drop_multiple' variant - for types with a real `Drop` impl, the current implementation is definitely optimal.
@bors bors bot changed the title Skip drop when needs_drop is false [Merged by Bors] - Skip drop when needs_drop is false May 17, 2022
@bors bors bot closed this May 17, 2022
@DJMcNab DJMcNab deleted the drop_opt_boogaloo branch May 17, 2022 06:19
robtfm pushed a commit to robtfm/bevy that referenced this pull request May 17, 2022
# Objective

- We do a lot of function pointer calls in a hot loop (clearing entities in render). This is slow, since calling function pointers cannot be optimised out. We can avoid that in the cases where the function call is a no-op.
- Alternative to bevyengine#2897
- On my machine, in `many_cubes`, this reduces dropping time from ~150μs to ~80μs.

## Solution
-  Make `drop` in `BlobVec` an `Option`, recording whether the given drop impl is required or not.
- Note that this does add branching in some cases - we could consider splitting this into two fields, i.e. unconditionally call the `drop` fn pointer.
- My intuition of how often types stored in `World` should have non-trivial drops makes me think that would be slower, however. 

N.B. Even once this lands, we should still test having a 'drop_multiple' variant - for types with a real `Drop` impl, the current implementation is definitely optimal.
exjam pushed a commit to exjam/bevy that referenced this pull request May 22, 2022
# Objective

- We do a lot of function pointer calls in a hot loop (clearing entities in render). This is slow, since calling function pointers cannot be optimised out. We can avoid that in the cases where the function call is a no-op.
- Alternative to bevyengine#2897
- On my machine, in `many_cubes`, this reduces dropping time from ~150μs to ~80μs.

## Solution
-  Make `drop` in `BlobVec` an `Option`, recording whether the given drop impl is required or not.
- Note that this does add branching in some cases - we could consider splitting this into two fields, i.e. unconditionally call the `drop` fn pointer.
- My intuition of how often types stored in `World` should have non-trivial drops makes me think that would be slower, however. 

N.B. Even once this lands, we should still test having a 'drop_multiple' variant - for types with a real `Drop` impl, the current implementation is definitely optimal.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective

- We do a lot of function pointer calls in a hot loop (clearing entities in render). This is slow, since calling function pointers cannot be optimised out. We can avoid that in the cases where the function call is a no-op.
- Alternative to bevyengine#2897
- On my machine, in `many_cubes`, this reduces dropping time from ~150μs to ~80μs.

## Solution
-  Make `drop` in `BlobVec` an `Option`, recording whether the given drop impl is required or not.
- Note that this does add branching in some cases - we could consider splitting this into two fields, i.e. unconditionally call the `drop` fn pointer.
- My intuition of how often types stored in `World` should have non-trivial drops makes me think that would be slower, however. 

N.B. Even once this lands, we should still test having a 'drop_multiple' variant - for types with a real `Drop` impl, the current implementation is definitely optimal.
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-Enhancement A new feature 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.

None yet

4 participants