-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Expand Miri's BorTag GC to a Provenance GC #118029
Conversation
This comment has been minimized.
This comment has been minimized.
That was 30 minutes without "Collect Me 🥺" mode, let's see what it is now... |
Of course that didn't do anything. Working with the test suite is never that easy. |
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.
Looks good, but I wonder what the effects on performance are.
Also, please add the testcase you posted in the other PR.
pub fn is_alloc_live(&self, id: AllocId) -> bool { | ||
self.tcx.try_get_global_alloc(id).is_some() | ||
|| self.memory.alloc_map.contains_key_ref(&id) | ||
|| self.memory.extra_fn_ptr_map.contains_key(&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.
Is it worth thinking about the order in which we check these? get_alloc_info
checks memory.alloc_map
first sine I assume that's the most common case.
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.
I tuned the order against the test 0weak_memory_consistency, because its runtime explodes after this PR with GC every block. I'll try some other programs.
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 a bit more into this. I've run (chunks of) the test suites for regex
, simd-json
, and http
and in all these cases > 40% of all the checks for an AllocId result in GlobalAlloc::Memory, but in the 0weak_memory_consistency test, the biggest hit is GlobalAlloc::Function (oddly enough the fraction of hits on functions climbs as the test goes on, not sure why, I'd expect every turn of the loop in that test to be the same).
Since all the global allocs can never be deallocated I think it might be worth stealing a bit from AllocId
so that the Id itself can locally indicate whether the allocation deallocated; that would let us skip over them in the GC without consulting a hash table.
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.
So you're saying we should stay with "global first" for now? Works for me.
Looks like a 2% improvement, based on bumping up the |
Could you run our entire benchmark suite, just to make sure we don't accidentally introduce a big regression somewhere? (I hope the default 10k blocks interval is enough that the GC is triggered a couple times during the benchmark.^^) |
Everything is within noise, except for the Commit I branched off:
This PR:
|
The benchmark that runs the GC the least is |
Running the |
Always setting -Zmiri-provenance-gc=1 even if we override it in 0weak_memory_consistency adds ~21 minutes to CI time. That's not great. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
~8 minutes total increase in CI time. That seems a bit excessive. Let's try applying the "just run pass tests" trick again? |
That shaved off maybe two minutes (uncertain of noise, not going to try checking). For all the targets without In my opinion, for now the best compromise is to just run one target with |
Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri The Miri subtree was changed cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
@bors r=RalfJung |
Expand Miri's BorTag GC to a Provenance GC As suggested in rust-lang/miri#3080 (comment) We previously solved memory growth issues associated with the Stacked Borrows and Tree Borrows runtimes with a GC. But of course we also have state accumulation associated with whole allocations elsewhere in the interpreter, and this PR starts tackling those. To do this, we expand the visitor for the GC so that it can visit a BorTag or an AllocId. Instead of collecting all live AllocIds into a single HashSet, we just collect from the Machine itself then go through an accessor `InterpCx::is_alloc_live` which checks a number of allocation data structures in the core interpreter. This avoids the overhead of all the inserts that collecting their keys would require. r? `@RalfJung`
This comment has been minimized.
This comment has been minimized.
# We set the GC interval to the shortest possible value (0 would be off) to increase the chance | ||
# that bugs which only surface when the GC runs at a specific time are more likely to cause CI to fail. | ||
# This significantly increases the runtime of our test suite, or we'd do this in PR CI too. | ||
if [[ -z "${PR_CI_JOB}" ]]; then |
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.
Ah, with -u
set, testing for the existence of a shell variable is not so easy any more... :/
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.
Ah! The place I got this from doesn't use -u
so I guess I'll do as that script does
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.
Ah, +u/-u dance seems safer (I really do hate shell scripting)
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 no please don't.
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.
[[ -z "${PR_CI_JOB-}" ]] should work, the
${PR_CI_JOB-default}syntax means "fall back to
default` if variable does not exist" and here we use an empty default.
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.
Hm. So we just need to lose -u for the whole script?
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.
Or modify the caller to always set the variable?
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.
No, just use "${PR_CI_JOB-}"
instead of "${PR_CI_JOB}"
@bors r=RalfJung |
@bors r- |
# We set the GC interval to the shortest possible value (0 would be off) to increase the chance | ||
# that bugs which only surface when the GC runs at a specific time are more likely to cause CI to fail. | ||
# This significantly increases the runtime of our test suite, or we'd do this in PR CI too. | ||
if [[ -z "${PR_CI_JOB:-}" ]]; then |
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.
I had suggested the version without :
, but with :
also works here.
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.
I tried to look up docs for shell expansion and I could only find the ones with :- documented and that's what the Miri repo uses. What changes if the colon is omitted?
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.
I can't find the page I got this from but https://stackoverflow.com/a/16753536 lists them all. They behave differently when the variable exists but is empty.
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.
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html says this before the list that has :-
etc
Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both parameter’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence.
I'd say the version without the colon is the more reasonable semantics (null != does-not-exist), but the shell world is weird.^^
@bors r+ |
Expand Miri's BorTag GC to a Provenance GC As suggested in rust-lang/miri#3080 (comment) We previously solved memory growth issues associated with the Stacked Borrows and Tree Borrows runtimes with a GC. But of course we also have state accumulation associated with whole allocations elsewhere in the interpreter, and this PR starts tackling those. To do this, we expand the visitor for the GC so that it can visit a BorTag or an AllocId. Instead of collecting all live AllocIds into a single HashSet, we just collect from the Machine itself then go through an accessor `InterpCx::is_alloc_live` which checks a number of allocation data structures in the core interpreter. This avoids the overhead of all the inserts that collecting their keys would require. r? `@RalfJung`
Rollup of 6 pull requests Successful merges: - rust-lang#116085 (rustdoc-search: add support for traits and associated types) - rust-lang#117522 (Remove `--check-cfg` checking of command line `--cfg` args) - rust-lang#118029 (Expand Miri's BorTag GC to a Provenance GC) - rust-lang#118035 (Fix early param lifetimes in generic_const_exprs) - rust-lang#118083 (Remove i686-apple-darwin cross-testing) - rust-lang#118091 (Remove now deprecated target x86_64-sun-solaris.) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#118029 - saethlin:allocid-gc, r=RalfJung Expand Miri's BorTag GC to a Provenance GC As suggested in rust-lang/miri#3080 (comment) We previously solved memory growth issues associated with the Stacked Borrows and Tree Borrows runtimes with a GC. But of course we also have state accumulation associated with whole allocations elsewhere in the interpreter, and this PR starts tackling those. To do this, we expand the visitor for the GC so that it can visit a BorTag or an AllocId. Instead of collecting all live AllocIds into a single HashSet, we just collect from the Machine itself then go through an accessor `InterpCx::is_alloc_live` which checks a number of allocation data structures in the core interpreter. This avoids the overhead of all the inserts that collecting their keys would require. r? ``@RalfJung``
As suggested in rust-lang/miri#3080 (comment)
We previously solved memory growth issues associated with the Stacked Borrows and Tree Borrows runtimes with a GC. But of course we also have state accumulation associated with whole allocations elsewhere in the interpreter, and this PR starts tackling those.
To do this, we expand the visitor for the GC so that it can visit a BorTag or an AllocId. Instead of collecting all live AllocIds into a single HashSet, we just collect from the Machine itself then go through an accessor
InterpCx::is_alloc_live
which checks a number of allocation data structures in the core interpreter. This avoids the overhead of all the inserts that collecting their keys would require.r? @RalfJung