-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Make Gc.compact do a complete compaction, add Gc.quick_compact #12859
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
|
Backseat naming comment: I don't think that quick_compact is in fact Obvious beginner question: should people just write |
|
I think it would be a significant improvement to leave the semantics of "quick_compact" seems idiomatic enough to me (although I'm not sure this is an operation I would ever really use). |
|
Ah, so the concern here is to remain compatible with the 4.x naming convention, which had only |
Backwards compatibility is a good reason to have For |
2272a88 to
22ec615
Compare
I think for long running workloads where you have realistically gone through many major collections it might be reasonable if you can't afford the cost of three synchronous stw collections. Compaction is currently the only way we release memory to the OS. That said, there is an argument for making Either way, I've added a test and some runtime events for |
gasche
left a comment
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.
With the discussion, I believe that the proposed change makes sense and that exposing the quick version is reasonable. The implementation now looks very similar to full_major, which makes more sense to me. Approved.
I am still not fond of the word quick for something that is not actually quick. I thought about partial_compact, but this may give the wrong intuition that we only compact a part of the major heap (while in fact we compact everything, but based on some stale information on what is and isn't free). Maybe just compact_without_full_major?
|
FWIW I like the change to make the semantics of |
|
|
|
|
|
|
|
The optional argument seems good to me (I might possibly suggest |
|
So one good argument against For example, we may want to make So I'm leaning back towards |
|
Maybe "incomplete" rather than "quick"? |
|
Or "approx", "best_effort", etc. |
|
I think it is worth noting that the semantics of a " Maybe we can com up with a name unrelated to (Also -1 to all uses of default arguments) |
|
What I hear is that we have neither a consensual API for "the other compact" nor a strong use-case. I think that the PR could move forward by splitting that part for later. |
|
@lpw25 there may be programs that have a steady regime made of large iterations, that want to release memory after each iteration. The goal is to ensure that if there is an infrequent memory usage spike, it does not affect the average memory usage. In that case the incomplete compaction is fine -- it may take two iterations to recover from a spike instead of one, but the throughput gains could be worth it. |
I'm in agreement here. I'll change the PR so it does a full major for |
22ec615 to
a54cd6d
Compare
this matches user expectations from 4's Gc.compact
a54cd6d to
76b3612
Compare
|
Right, two things to note here: I'm not convinced we need to empty the minor heap before calling Line 1358 in 76b3612
This logic is subtle though, so it would be good for someone else to double-check. I'm also happy to leave the extra minor collection and defer to another PR. The second thing to note is https://github.com/ocaml/ocaml/pull/12859/files#diff-dc06e9c510205e393752543cd6f306fc590813435584b4ea7fed68abc3c5a72cR4 Without that, |
ensure Gc.compact does a full major before the compactor runs this matches user expectations from 4's Gc.compact (cherry picked from commit 8e280b3)
Marked as draft because we may not want to merge. If there's consensus I'll add a few tests to the PR.
This PR makes
Gc.compactdo a full major cycle before compacting and adds aGc.quick_compactwhich only does a single one.The former ensures that everything unreachable before
Gc.compactis called will be swept and it's space potentially used to relocate blocks during compaction. In the latter, this is not the case, unreachable blocks beforeGc.quick_compactwon't be swept before compaction. This obviously results in a bigger heap afterwards. The trade-off is that there's a two thirds reduction in the number of heap traversals required. While it varies substantially by heap composition, I have very sparse heap benchmarks whereGc.quick_compacttakes only a third of the time thatGc.compactdoes.With this change
Gc.compactshould work similarly toGc.compactfrom 4.x (and matches the current doc on Gc.mli!) - not doing so has already caught out some early users.If we are going to do this, we should make sure this is part of 5.2 . (@Octachron )
probably of interest to @mshinwell @kayceesrk @damiendoligez