-
Notifications
You must be signed in to change notification settings - Fork 164
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
Remove the global hashtable for tracked fns with >1 argument #599
Comments
Mentoring instructionsTo start, #600 might be a good first step. Beyond that, but I can get you started with some pointers. Memos are stored in a Lines 16 to 18 in 710691d
Right now, each tracked function gets a Line 30 in 710691d
...which has an option, and thus can store 0 or 1 memos. The actual data is a The tricky part is that the keys of the map are the additional arguments and the type of memos is independent of those details. So you could package them up as an I'm not sure the best shape for the result. One idea I am toying with is that instead of having |
This is a partial reproduction of this comment, but I view this issue as a good place as any. Anyways: I've ported rust-analyzer over to the new Salsa, but noticed a non-trivial memory regression. A portion of this was me not wiring up the LRU functionality, but I'm decently sure that another chunk of the regression came from this issue. Here's why:
Based on my experimentation in #639, this means that my query group's generated code, as modeled in the code below, allocates 177,224 bytes of memory. #[salsa::input]
struct MyInput {
field: u32,
}
#[salsa::tracked]
fn tracked_fn<'db>(db: &'db dyn salsa::Database, input: MyInput, id: u32) -> u32 {
input.field(db) + id
}
#[test]
fn execute() {
let db = salsa::DatabaseImpl::new();
let input = MyInput::new(&db, 22);
let interned = 33;
assert_eq!(tracked_fn(&db, input, interned), 55);
} The following code, which is far more idiomatic under new Salsa, avoids the global hashtable and allocates only 95,164 bytes: #[salsa::input]
struct MyInput {
field: u32,
}
#[salsa::tracked]
fn tracked_fn(db: &dyn salsa::Database, input: MyInput) -> u32 {
input.field(db) * 2
}
#[test]
fn execute() {
let mut db = salsa::DatabaseImpl::new();
let input = MyInput::new(&db, 22);
assert_eq!(tracked_fn(&db, input), 44);
} I don't believe that removing Salsa's global hashtable would entirely close the gap between the query group macro and idiomatic Salsa, but I think it might make make a sizable impact depending on the shape of the solution. I imagine we'd be able to close the remainder of the gap through more idiomatic usage of Salsa. |
As described in this hackmd, we currently create an interned ingredient for every tracked function unless it has exactly 1 argument. This is wasteful. The reason we do this is because the memos for tracked functions are stored on salsa structs1 and so we need to have a 1:1 relationship between a (salsa struct, tracked fn) pair and a memo.
We should refactor things so that:
salsa
like#[salsa::intern] struct Placeholder<'db>{ data: () }
and redefine the argument as being called on aPlaceholder<'db>
, which we can trivially create (it'd also be nice to have a more optimized "global struct", maybe that's worth thinking about; even interning unit is more work than it really ought to be for this case).DashMap
instead of a single memo; the map would be keyed by the additional arguments.Footnotes
(Salsa struct = input | tracked | interned) ↩
The text was updated successfully, but these errors were encountered: