-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add snapshotting to ObligationForest #30965
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
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
(sorry - I had to rebase because of policies and incorrect e-mail addresses on commits and whatnot; I don't think anyone was in the process of commenting on the commits or anything anyway, though, so, shouldn't be a problem, jah?) |
pub struct Snapshot { | ||
len: usize, | ||
} | ||
// We could implement Copy here, but that tastes weird. |
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.
Nit: This comment is funny, but you could also say "but we expect each snapshot to be consumed exactly once".
@soltanmm I'm reading now. I initially thought that more complex snapshotting in the O.F. was not necessary, because we did not process obligations (and hence did not compress) while a snapshot was active. Is that not true? That said, I'm happy to see you've attempted something more aggressive, as I figured that sooner or later we'd have to add better snapshoting. I was planning on using a WAM-like technique -- which I think is sort of roughly what you've done, actually. I have to go review just what the WAM does here and compare it to the approach that you took. My main memory is that when popping contexts in a snapshot, you don't actually pop them, you keep the "stack pointer" at the end so as to avoid overwriting things that you may need to restore later. This might allows us to avoid the enumeration in |
OK, I understand better what you did. Makes sense, though I'm not sure what I think about maintaining e.g. a stack of states per node. I have to think about it. I also want to refresh my memory on what the WAM does in similar situations. I would be interested though to see the refreshed perf numbers you mentioned, since one of my concerns about this approach is that it makes the "baseline" case slower -- but then again since we're not really pushing many snapshots, I guess it's not quite as interesting as it might otherwise be. |
Oh. For some reason I thought that the compression not happening during snapshots was undesirable. What I wrote followed from that being desired and not thinking too much. :-)
Aye, that was done to avoid any extra allocations when not simultaneously snapshotting and processing obligations in the least-thinking-required-way. A stack of vecs of nodes w/ their parent pointers having choices between the current snapshot and the nth previous and identity backpointers (to keep track of outstanding dependency obligations across snapshots) would've had that property too (at the cost of complexity, methinks). Or just the single vec, but with node success status calculated by making a backward pass through the vec (with some second vec [or additional node fields] recording what's already been reported or not at what snapshot) instead of having that information explicitly present in the structure.
I'll grab some numbers again, but, yeah I'd be surprised at any significant decrease - the enum'd That all said, I think you're right on being iffy on the one-stack-per node. Want it differently? |
That was a little worse than I thought. I'll just do the not-as-lazy-way with a single vec some time later tonight and chuck it in tomorrow. EDIT: Clarification: those numbers were the most favorable comparison, the rest were worse. |
Makes ObligationForest support snapshots in a sophisticated wine-sipping way better suited for photo-shoots and other bad puns.
Updated to just use the single vec. A few cursory runs on Left a form of compression in (it was a little less complicated to think about that way). |
@nikomatsakis It just occurred to me that there was a possible gap in communication on my end now that I've actually reviewed what a WAM is. Did you actually really want something more like what's described here? (EDITEDIT: specifically having a separate 'trail' for the whole structure)
|
@soltanmm sorry for being incommunicado. Been a crazy week. Let me catch up on what you've done in the meantime. :) |
OK, I think I mostly grok what's going on here. I was thinking earlier that if I were going to add full snapshotting to the OF, I would probably do so by using a similar strategy to what we use elsewhere. That is, I would have an undo vector, and I would have snapshots being an index into that undo vector. When you start a snapshot, you would push an entry into the vector, so by checking if the vector is empty, you can test whether you are in a snapshot or not. The main data structure always stays at the "tip", and to commit a snapshot, you just clear the vector -- but to unroll one, you pop things off and undo them one at a time. See e.g. Following this approach, one could do something like:
Anyway, this feels like it might be simpler than what you've done here --- but maybe not. What do you think? Do you understand what I'm trying to describe? I'm still unsure whether to we will ever want this sort of transactional support in the OF though. Every scenario I can come up with where I would want it would, I think, be better served by making a separate fulfillment context for processing locally. But I'm not sure. |
@nikomatsakis No worries! And yep, gotcha. Undo list would probably be simpler sans rollbacks (I was really trying to avoid thinking much about rollbacks), so, h'okay. Will make another pass. EDIT: And I think I get why you wanted to keep as close to the baseline as possible (about preferring to spin off a new fulfillment context and whatnot). |
On Thu, Jan 21, 2016 at 09:24:31PM -0800, Masood Malekghassemi wrote:
I'm not sure, but that is what I meant by the WAM. I think perhaps |
Closing for #31175. |
Adds snapshotting to
ObligationForest
. The choice of using per-node vecs instead of additional tables or duplication was made under the assumption that if some node was getting hit with a snapshot+rollback, it'd probably get hit with another snapshot in the near future, and that we'd rather branch on superfluous nodes than (re)allocate some number of times at each snapshot. I haven't actually written the alternatives to test the potential performance difference though.I think I recall a <1% drop in runtime performance with this on top of the previous incarnation of
ObligationForest
onlibsyntax
at cursory glance. Can check again if desired.There are several FIXMEs sprinkled around. Mostly miscellaneous opportunities to perhaps optimize a bit.
r? @nikomatsakis (I think?)
cc @jroesch
EDIT: Needs tidying.