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

NavMap::sync(): only acquire write lock when writes are needed #96857

Closed
wants to merge 1 commit into from

Conversation

cgodley
Copy link

@cgodley cgodley commented Sep 11, 2024

Fixes #96820

  • Recommend viewing the diff with whitespace ignored (git diff -b). A large portion of the diff is indentation that didn't seem easily avoidable
  • Not 100% sure it's the best strategy or that I found 100% of the possible dirty flags. It's my first time contributing to Godot.
  • Works great in my local testing
  • Style: I'm not sure if is_dirty() is the best name. I used this name because check_dirty() elsewhere has side effects, but is_dirty() does not have any side effects. Feel free to change it.

@smix8
Copy link
Contributor

smix8 commented Sep 14, 2024

Thanks for looking into improving this. I agree the lock should only be held when needed.

I am just not sure if the changes here are the right fix. It just pushes the performance problems to situations where the map changes which are even more a problem for the average project. Doing a double-loop over all objects to check for dirty affects all projects performance by a small margin while it only fixes a very niche and extreme performance issue here.

The issue is that on a map with 35.000+ polygons, which is way, way too much, every single pathfinding thread blocks the map for 0.03 or more with the read lock. That is enough to make the map stutter on every tiny change by blocking the main thread because it needs to wait forever until a running read thread has finished before it can aquire the write lock. On a reasonable sized map the lock is held for such a small time window that the lock problem is marginal.

The likely real solution would be to move the pathfinding map to a static iteration that threads can run on without affecting the new iteration building. That unfortunately requires far bigger changes as no navobject is currently prepared for async updates. It is a big pointer and polygon legacy spaghetti.

@cgodley
Copy link
Author

cgodley commented Sep 14, 2024

Thank you for the fast reply. It makes sense we don't want to worsen anything related to map changes if that is an area people already have issues with.

Agree 35k polygons is high, my intention was to exaggerate the stutter in the MRP to make it easily visible during testing.

Closing the PR since I agree there are better ways to do this.

@cgodley cgodley closed this Sep 14, 2024
@AThousandShips AThousandShips removed this from the 4.x milestone Sep 14, 2024
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.

NavMap::sync write_lock blocks main loop when no write is necessary, causes unnecessary stuttering
3 participants