-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
QueryData/QueryFilter refactors and query lookahead
#22500
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
base: main
Are you sure you want to change the base?
Conversation
QueryData/QueryFilter refactors, and query lookaheadQueryData/QueryFilter refactors and query lookahead
|
It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note. Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes. |
No thanks 😅 I think this approach is clearer, and I really don't want to break user code that badly. |
|
I'd be very interested in seeing some rendering benchmarks for this too! |
Yeah, I thought not lol :)
Will do! I've been meaning to get one of the big glTF scenes set up locally to test |
Objective
Make query iteration faster, more flexible, and give query terms more control over how to iterate.
This PR implements "chunk-based query lookahead". Instead of checking the conditions for each row row-wise, we now check them column-wise, iterating forward for each term until we find the next contiguous "chunk" of valid rows. By passing the chunk returned by each query term to the next one, we can gradually narrow down our search area, like if we were short-circuiting in a row-wise check.
This works fine for normal query iteration (and is even faster by default in some cases!), but the main point is it gives query terms more control over how they iterate. In particular, this pattern is perfect for searching in something like a segment tree! The goal is for custom query terms (and changed detection eventually!) to be able to greatly speed up iteration where they need to.
It also might******* be more likely to auto-vectorize plain condition checking, there were vectorized loops in some of the asm dumps but I wasn't able to verify that it was condition checking in particular.
Solution
IS_ARCHETYPALontoWorldQueryWorldQuery::matches, leavingQueryFilterempty, andremoving the
Optionwrapper fromQueryData::fetch.WorldQuery::find_table_chunkandfind_archetype_chunkto let query terms determineif/how to seek ahead in the query.
QueryIter::fold/for_eachto use chunk-based iteration.NOTE: I had some strange performance issues with
QueryIter::next, so I left it as-is for now. I saw as much as a 50% performance hit in some benchmarks, and I was able to (mostly) fix it, but at the cost of a similar hit tofor_each. It feels like a weird bug though, so it seems worth coming back to eventually.Testing
Ran examples
Ran benchmarks:
none_changed_detection: 10-20% faster or no change vsmainfew_changed_detection: 40-55% faster vsmainall_changed_detection: ~20% faster vsmainfor table iteration, ~20% slower for sparse (that feels like a bug, will investigate)iter_simple: generally no change, 15% faster forwide_sparse_set, 3-4% slower forforeach_hybridandpar_hybriditer_frag: generally no change, a few were faster by 5-7% and a few were slower by 5-10%heavy_compute: no change vsmainNeeds real world testing! I don't have a good representative benchmark myself.
Future Work
AddedandChangedQuery::nextQueryinto one