-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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] - Make System
responsible for updating its own archetypes
#4115
Conversation
This was suggested in the discussion on https://discord.com/channels/691052431525675048/947636849139150868 with @alice-i-cecile and others - it turned out to be pretty simple, so sending this to see what folks think. |
Instead of replacing the Some users (and mocking up tests) might still want to register only specific archetypes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall as long as this doesn't change perf too much, I think it makes sense as a low level api for people to run systems outside of the executor.
crates/bevy_ecs/src/system/mod.rs
Outdated
for archetype in world.archetypes.iter() { | ||
system.new_archetype(archetype); | ||
} | ||
system.update_archetypes(&world); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test doesn't really check if the archetypes are updated correctly. Since this new function is part of the public api that we expect to be used, should we be adding more tests to check correctness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I like this change quite a bit:
Positive:
- less duplication of complex, critical logic
- essential for safe third-party implementations of custom executors or other scheduling strategies
Unsure:
- how this affect performance, if at all?
Requested changes:
- I would like to see some more robusts tests to verify that this works, with an emphasis on scenarios that were previously impossible
- docs nits
I'm not sure how common a use case that would be - it seems like it makes the API rather less clear to have both? The interaction between the two isn't really obvious. If there's a general consensus that it's likely to be useful then I can restore it, and just try to describe the behaviour more thoroughly, though. The other comments all make sense; I agree that better naming would help here, especially if keeping both functions. To propose yet another combination, Since it seems like there's general agreement that this is desirable for the API, I'll see about benchmarking it and adding test coverage. |
Still need to work on tests/docs but wanted to see what folks think of this basic set of benchmarks, which don't show any difference outside of noise for me. |
This seem extremely implausible to me. IMO if this is the best argument in favor of keeping it it should be cut for sure. |
(also this is the first time I've actually used github PR code review so am not entirely sure of expectations around resolving comments etc) |
Could you post the benchmark results in the PR description? It's helpful context for reviewers: no change is good news!
Resolve comments once the changes are addressed :) If there are interesting but unactionable comments / call-outs, keep those around so folks can see those on later review / just before merge. |
Results of the benchmark without the change:
and with the change:
I re-ran this on my giant desktop instead of my ultrabook and there things are less noisy, so it does become statistically significant. |
Hm. Actually it's still pretty noisy on this machine too even with CPU frequency locked. |
Thanks for benchmarking, I was hoping there wouldn't be much of a change since we'll still be registering archetypes the same number of times. Good to have some confirmation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from two nits, this looks good to me.
So with the updated benchmark here I'm actually seeing performance on I'm still thinking about tests to add here but am pretty happy with the form it's in now; thanks for the continued discussion all! |
critcmp is a pretty common and standard solution here. |
Ah, I have a hypothesis for why the performance might have actually improved for large numbers of new archetypes - previously the update loop in the executor was iterating over all the new archetypes and passing each to every system in turn, but this is now iterating over the systems and having each deal with all the new archetypes, which seems likely to have better locality? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks great. Less code, and is potentially faster? Sounds great to me. Just one thing: could you use critcmp
as suggested above and provide a solid comparison between the results from before and after?
Add a simple unit test for update_archetype_component_access to ensure that the access is properly updated.
Well, with the simple unit test I added above it does look like things are working; if folks have suggestions for more things to test I can give it a shot? While I'm still a little sceptical of the benchmark results being particularly meaningful, it doesn't appear to have broken anything? :) |
OK; I'm considering this done. If folks have other suggestions I can take a look. |
Co-authored-by: Alice Cecile <[email protected]>
bors r+ |
# Objective - Make it possible to use `System`s outside of the scheduler/executor without having to define logic to track new archetypes and call `System::add_archetype()` for each. ## Solution - Replace `System::add_archetype(&Archetype)` with `System::update_archetypes(&World)`, making systems responsible for tracking their own most recent archetype generation the way that `SystemState` already does. This has minimal (or simplifying) effect on most of the code with the exception of `FunctionSystem`, which must now track the latest `ArchetypeGeneration` it saw instead of relying on the executor to do it. Co-authored-by: Carter Anderson <[email protected]>
Canceled. |
bors r+ |
# Objective - Make it possible to use `System`s outside of the scheduler/executor without having to define logic to track new archetypes and call `System::add_archetype()` for each. ## Solution - Replace `System::add_archetype(&Archetype)` with `System::update_archetypes(&World)`, making systems responsible for tracking their own most recent archetype generation the way that `SystemState` already does. This has minimal (or simplifying) effect on most of the code with the exception of `FunctionSystem`, which must now track the latest `ArchetypeGeneration` it saw instead of relying on the executor to do it. Co-authored-by: Carter Anderson <[email protected]>
Build failed: |
bors r+ |
# Objective - Make it possible to use `System`s outside of the scheduler/executor without having to define logic to track new archetypes and call `System::add_archetype()` for each. ## Solution - Replace `System::add_archetype(&Archetype)` with `System::update_archetypes(&World)`, making systems responsible for tracking their own most recent archetype generation the way that `SystemState` already does. This has minimal (or simplifying) effect on most of the code with the exception of `FunctionSystem`, which must now track the latest `ArchetypeGeneration` it saw instead of relying on the executor to do it. Co-authored-by: Carter Anderson <[email protected]>
System
responsible for updating its own archetypesSystem
responsible for updating its own archetypes
Thanks; I didn't intend to leave the println calls in there but since they get swallowed during normal test runs I forgot :) |
…#4115) # Objective - Make it possible to use `System`s outside of the scheduler/executor without having to define logic to track new archetypes and call `System::add_archetype()` for each. ## Solution - Replace `System::add_archetype(&Archetype)` with `System::update_archetypes(&World)`, making systems responsible for tracking their own most recent archetype generation the way that `SystemState` already does. This has minimal (or simplifying) effect on most of the code with the exception of `FunctionSystem`, which must now track the latest `ArchetypeGeneration` it saw instead of relying on the executor to do it. Co-authored-by: Carter Anderson <[email protected]>
…#4115) # Objective - Make it possible to use `System`s outside of the scheduler/executor without having to define logic to track new archetypes and call `System::add_archetype()` for each. ## Solution - Replace `System::add_archetype(&Archetype)` with `System::update_archetypes(&World)`, making systems responsible for tracking their own most recent archetype generation the way that `SystemState` already does. This has minimal (or simplifying) effect on most of the code with the exception of `FunctionSystem`, which must now track the latest `ArchetypeGeneration` it saw instead of relying on the executor to do it. Co-authored-by: Carter Anderson <[email protected]>
Objective
System
s outside of the scheduler/executor without having to define logic to track new archetypes and callSystem::add_archetype()
for each.Solution
System::add_archetype(&Archetype)
withSystem::update_archetypes(&World)
, making systems responsible for tracking their own most recent archetype generation the way thatSystemState
already does.This has minimal (or simplifying) effect on most of the code with the exception of
FunctionSystem
, which must now track the latestArchetypeGeneration
it saw instead of relying on the executor to do it.