-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
perf: Merge done_cache and active_cache in ObligationForest #67892
Conversation
Removes one hash lookup (of two) in `register_obligation_at`.
r? @davidtwco (rust_highfive has picked a reviewer for you, use r? to override) |
@bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit ef83c93 with merge 00f61087aa85f4929c9cc4e71b161f462cfbea97... |
cc @nnethercote |
☀️ Try build successful - checks-azure |
Queued 00f61087aa85f4929c9cc4e71b161f462cfbea97 with parent 7785834, future comparison URL. |
r? @nnethercote (thought he's currently on PTO, might be worth re-assigning but I'm not sure who else is a good choice) |
rust-timer didn't post the completion message and the regressions look rather excessive... The changes should really just make it do less work (modulo some added branches which should not affect things much). |
&mut self, | ||
obligation: O, | ||
parent: Option<NodeIndex>, | ||
) -> Result<(), ()> { | ||
match self.active_cache.entry(obligation.as_predicate().clone()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This now clones the predicate even when it is done. Maybe that is the problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looked into it the predicate type, it is always a ty::Predicate
(or &str
in tests) which is copyable and only takes up 32 bytes which isn't tiny but shouldn't really affect things...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, ok I think it is because active_cache
now gets really big, so the retain
becomes really expensive as it fills up with None
values...
The `alternative_predicates` is instead used to track when predicates changes so that they still get removed/marked as done on completion. Unsure if this is the best way but it seems to work.
I think I have a way to remove the As a side effect the need for rewriting node indices in |
Let's give this another go then. @bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit f33df29 with merge 20e1c5fd4d787c557ee4c2b745ff727a5e3e87a5... |
☀️ Try build successful - checks-azure |
Queued 20e1c5fd4d787c557ee4c2b745ff727a5e3e87a5 with parent ebbb2bf, future comparison URL. |
Finished benchmarking try commit 20e1c5fd4d787c557ee4c2b745ff727a5e3e87a5, comparison URL. |
Closing until I can figure out a way to avoid the regressions. |
I'm late to the party here, due to PTO, but my main comment is that |
I am aware that it can be really hot (that's why I looked at improving it!). While there are many micro optimizations which help improve the status quo the algorithm as a whole I do believe it can be improved, iterating and filtering through all obligations on each process_call can definitely baloon in runtime if it ends up going through it multiple times without being able to actually remove any obligations (I suspect this is part of the problem in #68666, though lack of memoization is probably the main problem) |
Looked into why This makes it clear why So to actually get some wins here we need to do one or more of the following
|
In the first commit, then a couple of refactorings to clarify
ObligationForest