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
Bigarray sub-arrays counted towards total out-of-heap memory usage #12491
Comments
I looked at the code, agree that there is an issue worth fixing, and discuss some options I see to fix the bug. Hopefully people who know bigarrays better can chime in with preference regarding potential fixes.
Currently its I see two different approaches to fix the issue:
Note that for some user code the same over-counting may occur (as in the runtime) and so (1) would also fix the issue in user code while (2) would keep over-counting (if the user does not update their code to use Another solution might be to tune |
I thought more about this and now believe that approach (1) is always the right choice when the I propose PR #12493 with a bugfix, which is fairly small/uninvasive. With this bugfix, the proposed testcase terminates immediately. |
Thinking more about this, I am not sure what semantics a user should have in mind when calling
This bugfix assumes (1), but (2) is also a possibility. In this case the calls to |
I looked at some user code found through Github code search, and I can see several cases where I believe that the
The fix proposed in #12493 would be incorrect in this case -- where I believe we should increase GC pacing, so I closed that issue. I think that a better fix would be to introduce an |
@gasche, thanks so much for the prompt response and fix! Regarding the ownership transfer use case you mentioned, it seems a bit fragile due to the prerequisites for the transferred memory block (must reside on the same heap, freeable with free()). Case in point, out of the three examples you noted above, it looks like two might be problematic? For the unison case, unless I'm missing something, the data transferred does not necessarily point directly to memory allocated by malloc, so freeing it later on could result in memory corruption. For the core case, wouldn't the GC pace be a bit off here? It looks like caml_ba_alloc is called with the original dim, so the GC pace would be increased by that amount and not by the new size, and moreover, not sure the old (freed) allocation size is taken into account? Not suggesting that there's anything wrong with your change however, just that it's a tad tricky to get it right :) |
Good points.
|
Regarding (2), even if it did that, would the old memory block size (that's now freed) be accounted for? |
(Indeed, this was an unsatisfying suggestion and I edited it out in the meantime.) |
Digging a bit further: there is more code on the web that assumes that
And just for fun there is also code that uses |
(Xavier sent me his own fixes for this and I need to do the work of comparing them and blessing one of them for upstreaming. I hope to get to it soon.) |
) This is achieved by adding a CAML_BA_SUBARRAY flag that is honored by caml_ba_alloc. Fixes: ocaml#12491 Closes: ocaml#12500
The following code snippet demonstrates the issue:
From a quick look, it appears that creating sub-arrays of bigarrays may result in excessive GC cycles. For example, running the above snippet, the top offenders according to perf are:
From what I can tell, the out-of-heap amount is increased as a result of calling
caml_ba_alloc
even if no out-of-heap memory is actually being allocated. To make things worse, sincecaml_ba_sub
callscaml_ba_alloc
with the original dimensions, the size of the whole (original) bigarray is counted towards the total out-of-heap memory.The text was updated successfully, but these errors were encountered: