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

Add Active Object Spatial Cache #14643

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ExeVirus
Copy link
Contributor

@ExeVirus ExeVirus commented May 12, 2024

This PR adds a simple cache to server active objects (SAOs) based on position. This PR was made to solve the problem outlined in #14613, hoping to improve by orders of magnitude our ability to handle more entities in Minetest, and to make more performant ways to get objects in a given area/radius.

This directly addresses section 2.4 of the current roadmap for minetest. It specifically calls out the old version of the issue this task tries to address.

The implementation is best described as a single-layer of buckets implemented using unordered_multimap, which is a fancy term for "It's sorts entities into buckets the same size as mapblocks (16x16x16)". When you ask for entities in a given area/radius, this map allows you to filter out the vast majority of irrelevant entities.

Performance:

  • 2-5x faster inArea and inRadius lookups, for most games/servers
  • inArea is now slightly more performant than inRadius checks, depending on entity dispersal
  • If all your 1000 entities are in a single mapblock (16x16x16): this map doesn't help you.

Areas where the cache is integrated in this PR:

  • getObjectsInRadius
  • getObjectsInArea
  • getAddedActiveObjects
  • getSelectedActiveObjects
  • collisions

Builtin Benchmarking

image

To do: Done

  • Create performant, simple position based data structure
  • Add benchmarks to verify exactly what the tradeoffs are of this versus current master
  • Perform side-by-side benchmarking metrics
  • Create initial PR to get code cleaned up for merge
  • Integrate new cache with server::ActiveObjectManager
  • Ensure cache is updated on every entity move, insertion, and deletion.
  • Integrate cache capabilities throughout Minetest, such as helping with per-client SAO updates, etc.
  • Make code to match Minetest style guidelines, and integrate into the proper C++ files in the engine
  • Run with a full test server to verify nothing is broken (beyond unit tests already performed)

How to test

benchmarking:

  1. Enable benchmarking in your c++ cmake settings
  2. Build
  3. run minetest.exe --run-benchmarks
  4. checkout master, and bring over this branch's benchmark_activeobjectmgr.cpp for A to B comparison
  5. recompile
  6. run minetest.exe --run-benchmarks

Stability/Correctness

Stable and Validated

I have done extensive testing using a pseudorandom test function that tests insertion and removal of SAO's during iteration through SAOs, as well as testing inRadius and inArea checks and moving all found entities, and veriified that master and this branch have identical results for all steps after 20x200 iterations of 1000 entities. That function for your review is here Note that I am not advocating its inclusion; it's only useful for this one core change and not much thereafter.

Slight Difference compared to master

Using this new spatial map, when we iterate over entities during an inArea or inRadius search, it is now possible for some (not all) entities that are added during iteration to be found within the current search iteration. Future work may want to take this some steps further to guarantee all added objects are checked for the current search iteration, and that may be a solution to #14614. That is future work, however.

@wsor4035 wsor4035 added WIP The PR is still being worked on by its author and not ready yet. Performance labels May 12, 2024
Copy link
Contributor

@appgurueu appgurueu left a comment

Choose a reason for hiding this comment

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

gave it a quick look

src/benchmark/benchmark_activeobjectmgr.cpp Outdated Show resolved Hide resolved
src/benchmark/benchmark_activeobjectmgr.cpp Outdated Show resolved Hide resolved
src/benchmark/benchmark_activeobjectmgr.cpp Outdated Show resolved Hide resolved
src/server/spatial_map.cpp Outdated Show resolved Hide resolved
src/server/spatial_map.h Outdated Show resolved Hide resolved
src/server/spatial_map.h Outdated Show resolved Hide resolved
src/server/spatial_map.cpp Outdated Show resolved Hide resolved
@ExeVirus ExeVirus force-pushed the feature/exevirus_optimize_server_object_lookups branch 2 times, most recently from 9659ff0 to 6f0c224 Compare May 16, 2024 04:25
@ExeVirus ExeVirus force-pushed the feature/exevirus_optimize_server_object_lookups branch 2 times, most recently from 138beb3 to f0d41f6 Compare June 11, 2024 18:37
@ExeVirus ExeVirus force-pushed the feature/exevirus_optimize_server_object_lookups branch from f0d41f6 to 7e504cb Compare June 11, 2024 18:38
@Zughy Zughy added Bugfix 🐛 PRs that fix a bug and removed WIP The PR is still being worked on by its author and not ready yet. labels Jun 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bugfix 🐛 PRs that fix a bug Performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants