-
Notifications
You must be signed in to change notification settings - Fork 202
Shrink DatabaseKeyIndex to 8 bytes to save memory
#1045
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: master
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for salsa-rs canceled.
|
CodSpeed Performance ReportMerging #1045 will improve performance by 8.51%Comparing Summary
Benchmarks breakdown
|
005814e to
35a1b50
Compare
|
GitHub actions out of storage... |
|
Nice, there are some test failures (re-running fixed the temporary out-of-disk-space error) |
35a1b50 to
9477be1
Compare
|
Something weird happens with CI... |
|
Okay I deleted the ci caches, lets see if that helps |
9477be1 to
0298d29
Compare
|
Yea looks like llvm/ld just likes to freak out when the diskspace runs out lol |
|
This is cool. Will try to review after the holidays. Happy holidays to all of you |
|
Unfortunately, this breaks our test infrastructure: let event = events.iter().find(|event| {
if let salsa::EventKind::WillExecute { database_key } = event.kind {
db.ingredient_debug_name(database_key.ingredient_index()) == query_name
} else {
false
}
});Because calling |
|
The perf and memory improvements on ty are very impressive. But we now have some tests that timeout. Not sure why astral-sh/ruff#22203 |
We can probably change the fields of that event and just deconstruct the key eagerly, since the event infra is callback based one only pays when a callback is registered after all |
|
Or alternatively expose a public getter that takes a |
0298d29 to
e7bfe82
Compare
Edited to do this. |
As well as the timeout on the corpus test, there are also some ty mdtests on that PR that are panicking with "too many cycle iterations" |
|
I tested this with rust-analyzer and it worked, however we have no fixpoint iteration currently, therefore there might be bugs there. I'll try to understand where the problem is. |
Via the observation that: - The `IngredientIndex` can be retrieved from the page, except for tracked fns - The generation is useless, except for interneds And since they don't overlap, we can store only what needed for each.
Because we sometimes get id from a `DatabaseKeyIndex` that doesn't have the generation, so it prevent conflicts. And we don't need it either, as explained in a comment.
e7bfe82 to
635405d
Compare
|
I tried to debug the issue on the ty repo. I did manage to reliably reproduce the issue ( |
|
Yeah, this might require staring at logs for a very long time to see where (I suspect fixpoint) goes wrong. |
| /// Returns the database key index for a tracked struct with the given id. | ||
| pub fn database_key_index(&self, id: Id) -> DatabaseKeyIndex { | ||
| DatabaseKeyIndex::new(self.ingredient_index, id) | ||
| DatabaseKeyIndex::new_non_interned(self.ingredient_index, id) |
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.
We use generations for tracked structs that are reused to avoid an extra read dependency, not just interned values. This might be the cause of the test failures?
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.
If we use the generation for tracked structs, the whole idea falls, since tracked structs need the generation, but they also need the ingredient index, as sometimes we want to refer to one of the fields (different ingredient) but the page is the same.
Are we surely need the generation for tracked structs? What did we do before the introduction of generational IDs?
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.
It probably required a read dependency when reading an untracked field, see #864
I don't fully remember why we changed TrackedStruct also. Was it just because we had generational ids or was it because it was required for interned struct LRU.
I'm also inclined to encode the iteration into the Salsa id... but that's not definite yet.
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.
Yeah, it's not strictly necessary, but it was meant to be a performance improvement (though I'm not sure it ended up being a significant one).
Via the observation that:
IngredientIndexcan be retrieved from the page, except for tracked fnsAnd since they don't overlap, we can store only what needed for each.
For rust-analyzer, this saves 55mb on itself and 200mb on a large codebase (omicron).