Improve realism of entity benches by warming up the entity allocator #22639
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
As per this comment on #18670, this PR attempts to make entity related benchmarks more realistic by warming up the entity allocator. This helps test the freelist in the entity allocator.
Solution
This PR introduces a new
WorldBuildertype that starts withWorld::new, allows configuration options for warming up the world via the builder pattern, and then builds the warmed up, realistic world. For now, the only available "warm up" is for entities, but we could also add functionality in the future to cache bundle info, pre-create tables, etc to make our benchmarks more realistic. That is, more closely match the performance of a running app, rather than an app at startup.The current implementation for entity warmups allocates some entities and frees them in a random order. It also spawns the highest allocated entity index to prepare
Entities's location storage, etc. This involves usingrng(deterministically), but without this, the entities are allocated in a linear index order (0, 1, 2, ...), which is unrealistic and extremely cache friendly (so it probably makes an impact in performance not desirable for a benchmark).The major downsides here are that the benches take a little longer to run now and that startup/caching time is no longer benchmarked. That is for example, that benchmarking despawning only one entity used to tell us some information about performance of allocating the free list (amongst other one time actions). Now, that information is lost since the world is already warmed up. In practice, for N values of entities, it used to be the case that a higher N showed the performance of the operation, and a lower N showed the performance of the operation + any registration/caching costs. Now, the different N values only tell us more about how well the CPU accommodates a batch of the operation.
Currently in Bevy, making a change might make the
...1_entitybenches much worse but the...1000_entitiesmuch much better because the change added some new caching. The inverse is also common. With this PR, that will no longer be the case, at least for entities and whatever else we add to theWorldBuilderin the future. And that change may or may not be desirable.Testing
Ran a sampling of the benchmarks.