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

Make NavMap objects request sync only on demand #99646

Merged
merged 1 commit into from
Nov 29, 2024

Conversation

smix8
Copy link
Contributor

@smix8 smix8 commented Nov 24, 2024

Replaces brute-force sync check loop with a self-listing system where each map navobject is responsible for its own sync, requesting the sync only on demand once.

Previously each NavMap::sync() the map looped over every single navobject on the map on the main thread. For each physics step it looped over all regions, links, agents and obstacles, to check if any of them are dirty and needed to be synchronised. If dirty it called their sync function or whatever equivalent on the main thread in the middle of the physics step iteration.

Let's just say having potentially thousands of unchanged navobjects on the map checked every single physics step and updated on the main thread was less than ideal. Doing all the more costly sync updates while blocking physics on the main thread was even worse. Who would have guessed?

This PR does not change things about the threading but it prepares the base. Even if performance was a minor incentive for this change the current system was also not long-term sustainable with more and more different navobjects added or additional sync points required for async updates. This PR mostly copies how this is handled by similar servers or classes.

@fire
Copy link
Member

fire commented Nov 24, 2024

Do you have a method for testing this like a test project?

@smix8
Copy link
Contributor Author

smix8 commented Nov 24, 2024

Do you have a method for testing this like a test project?

For stability test just spawn, change, and delete (ten) thousands of NavigationRegion3D, NavigationLink3D, NavigationAgent3D and NavigationObstacle3D nodes at random intervals between physics steps until your CPU catches fire.

Also helps when the reported debug monitor navigation section numbers make sense after every change.

The --test -test-suite= *[Navigation]* already confirmed that there are no (major?) sync errors because those tests expect a valid result directly after a single sync, else the tests start screaming which I had multiple times while working on this.

Performance testing in a vacuum is mostly pointless for this PR as it was sliced from a bigger PR for async synchronisation missing the main accompanying pieces. I am piecemealing that larger PR atm with smaller PRs like here to escape the rebase hellscape as best as I can.

@Repiteo
Copy link
Contributor

Repiteo commented Nov 26, 2024

Even if it's redundant in isolation, some performance metrics would be nice — if only to ensure that this isn't regressing current behavior. I have no real reason to believe there's been a regression, but I believe this is a practice we're wanting to employ for performance PRs moving forward

@smix8
Copy link
Contributor Author

smix8 commented Nov 26, 2024

In general I agree but as mentioned a performance test for this PR is mostly pointless in isolation without all the other async update related PRs that follow. If this is more about the performance label we can just remove it from this PR.

It is like the theoretical discussion if adding code that starts and joins a thread costs more and causes a performance "regression". Sure it does, but that is not the point, the point is to offload things from the main thread because the single-threaded way is already no longer working. You can't do async updates while the map sync is just for-looping over everything like a donkey kong.

@smix8 smix8 removed the performance label Nov 26, 2024
Copy link
Contributor

@Repiteo Repiteo left a comment

Choose a reason for hiding this comment

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

Fair enough. I'm not about to police a policy I'm not even sure exists, especially when it's mostly semantics in this context. The intent of this PR is extracting a bite-sized portion to make introducing the overall package more streamlined, and it succeeds at exactly that

modules/navigation/nav_map.h Outdated Show resolved Hide resolved
modules/navigation/nav_map.h Show resolved Hide resolved
Replaces brute-force sync check loop with a self-listing system where each object is responsible for its own dirty sync, requesting it on demand only.
@smix8 smix8 force-pushed the navmap_sync_dirty branch from 2664ee6 to ba5a357 Compare November 27, 2024 00:00
@akien-mga akien-mga merged commit 6f4cb10 into godotengine:master Nov 29, 2024
20 checks passed
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants