Systems with parallelizable mutable access to multiple worlds. #16933
Labels
A-ECS
Entities, components, systems, and events
C-Feature
A new feature, making something new possible
D-Modest
A "normal" level of difficulty; suitable for simple features or challenging fixes
S-Needs-Design
This issue requires design work to think about how it would best be accomplished
TLDR
This proposes systems that can reference multiple worlds mutable while maintaining maximum parallelization. This could open up the doors for dramatic performance improvements down the road, especially in extraction schedules for sub-apps. It would also improve/replace some utility abstractions found in bevy_render, making similar performance gains possible for additional sub-apps, most notably physics sub-apps.
What problem does this solve or what need does it fill?
Currently, communicating mutably between two worlds is challenging. This comes up a lot during extract phases for sub-apps, which ends up being a performance bottleneck because it limits what can be parallelized. Bevy has some abstractions that make this more convinient, especially in bevy_render, but they all have some form of limitation.
It would be great to be able to be able to have a resource that contains a World, or World ptr, etc, which can then be referenced by system parameters. For example, something like this:
This is similar to bevy_render's Extract system parameter, but that only works for read-only access. Other abstractions are possible but are complicated because of the following:
Currently the above magical abstraction is not feasible because the SystemMeta's access lists do not store WorldIds. In other words, my_system is invalid because it requires multiple mutable accesses to the Time resource, even though the ResMuts actually refer to different worlds.
What solution would you like?
I am no expert in the internals of bevy's ecs, but it looks to me that by adding a WorldId to each ComponentId and ArchetypeComponentId in the SystemMeta Access list, these abstractions would be possible.
To prevent the memory overhead of storing largely redundant WorldIds (usually it will all be for the same world), it would be more realistic to have one Access and FilteredAccessSet per WorldId that the system references.
This is definitely contentious and is just an idea. I am very open to alternatives.
What alternative(s) have you considered?
It seems to me that the best alternatives currently possible are from bevy_render's Extract family of abstractions, but those have the downsides and reduced capabilities as shown above. These abstractions could be improved and moved to another crate. I would imagine similar patters are used in various other community sub-apps, especially physics sub-apps.
Alternatively, each conflicting component and resource could be wrapped in a type like
FromWorld12<ComponentType>
, but that involves redundant registrations and requires compile-time knowledge of the different worlds.Additional context
This issue deals with mutable communication. I recently opened a related issue for immutable communication, #16923. That has more context for my specific use case, but the nature of these issues are different.
Depending on the how this is implemented, it may need to be designed for/around #16618.
Benefits
If some version of this is implemented, here are some potential benefits down the road:
The text was updated successfully, but these errors were encountered: