Bevy version
0.12.1
Relevant system information
- CPU: AMD Ryzen Threadripper 3970X 32-Core Processor 3.69 GHz
- RAM: 32GB
What you did
Hello! I have a use-case that essentially involves separating identical groups of entities. Since Bevy's subworld support is not complete and Bevy does not have shared components (like Unity DOTS), I opted for a solution where I use Rust generics to "duplicate" my systems for every group with a SpareSet marker component. So Marker::<0>, Marker::<1>, ... components and SystemA::<0>, SystemA::<1>, ... systems. The idea was the separate systems/marker components will allow Bevy to properly parallelize logic across groups since there are no cross-group dependencies.
What went wrong
It seems Bevy is bottlenecked by the number of systems for my use-case. Attempting 6000 systems (2000 groups, 3 systems/group) results in 7% CPU utilization with 12 FPS. A Tracy capture indicates that 80+% of the CPU time is spent in the multithreaded executor before sending tasks to my thread pool.
I have created a Github with the capture and code https://github.com/UsaidPro/BevyLotsOfSystems
I was hoping Bevy would distribute the systems across the full thread pool provided by my 32-core CPU. However, instead what happens is 1 core gets consumed by the multithreaded executor which does distribute the tasks across all threads (I see 55+ thread pools in Tracy) but only after taking ~60+ms (80+% of compute time). The multithreaded executor has MTPC of 470us, but it is called 17k times compared to 129 Update calls resulting in 83% of time spent in the single thread.
Here is a table of what systems vs FPS. All these used only 7% of my CPU, same bottleneck. I have 3 systems, 1 of them only runs if run_if() returned true.
| Groups |
Concurrent Systems |
Conditional Systems |
FPS |
| 2000 |
4000 |
2000 |
12 |
| 1000 |
2000 |
1000 |
40 |
| 500 |
1000 |
500 |
60 |
Additional information
Tracy screenshot:

Bevy version
0.12.1
Relevant system information
What you did
Hello! I have a use-case that essentially involves separating identical groups of entities. Since Bevy's subworld support is not complete and Bevy does not have shared components (like Unity DOTS), I opted for a solution where I use Rust generics to "duplicate" my systems for every group with a
SpareSetmarker component. SoMarker::<0>, Marker::<1>, ...components andSystemA::<0>, SystemA::<1>, ...systems. The idea was the separate systems/marker components will allow Bevy to properly parallelize logic across groups since there are no cross-group dependencies.What went wrong
It seems Bevy is bottlenecked by the number of systems for my use-case. Attempting 6000 systems (2000 groups, 3 systems/group) results in 7% CPU utilization with 12 FPS. A Tracy capture indicates that 80+% of the CPU time is spent in the
multithreaded executorbefore sending tasks to my thread pool.I have created a Github with the capture and code https://github.com/UsaidPro/BevyLotsOfSystems
I was hoping Bevy would distribute the systems across the full thread pool provided by my 32-core CPU. However, instead what happens is 1 core gets consumed by the
multithreaded executorwhich does distribute the tasks across all threads (I see 55+ thread pools in Tracy) but only after taking ~60+ms (80+% of compute time). The multithreaded executor has MTPC of 470us, but it is called 17k times compared to 129 Update calls resulting in 83% of time spent in the single thread.Here is a table of what systems vs FPS. All these used only 7% of my CPU, same bottleneck. I have 3 systems, 1 of them only runs if
run_if()returned true.Additional information
Tracy screenshot:
