Want non-allocating array views
timholy opened this issue · 10 comments
I couldn't find an open issue for this frequently-noted problem, so I'm filing this. Feel free to close if there's an earlier one.
It's worth linking to https://groups.google.com/forum/#!topic/julia-users/6Z1kJ5LrSMU, where it was pointed out that "faking" a view as (A, R)
, where R
is a CartesianRange
, is currently the cleanest way to circumvent this problem (but can only handle the equivalent of Int/UnitRange/Colon
indexes). Various solutions using Ptr
have also been employed in the past, but of course those suffer from the standpoint of garbage-collection safety.
I suppose all we need for this is e.g. #12205
#12205 is basically working (still a last problem that I can fix) but for the whole thing to work we need to change the storage convention so that !pointerfree immutables are treated in the same way as bits one.
That means storing them inline in arrays/other types (requires gc support, I can do that). It also means (when specSig) passing them by value as arguments (or pointers if too large), and returning them by value too (if not too large).
We may want that to be opt-in per type since it will change the memory layout as @yuyichao noted.
As locals they can just be stored on the stack, the only difference with bitstype is that they will not be scalarized by llvm since we need a pointer to it for GC. Using TBAA we can probably just have it load the values once though.
I feel most of it is in codegen so it would be a lot easier to do that with you @vtjnash. If the idea looks sound to you we can decide for a couple of days where we just sit down and go through it if you want.
Seems reasonable ?
Sorry for spamming this thread but any idea when this could land into the base ?
The current view
function still allocates memory. This causes slowdown when lengthy arrays are repeatedly accessed with various views. As a temporary measure, I have been using unsafe_aview
(from ArrayViews.jl) function but that package has some depreciation warnings on Julia 0.6 and am worried that it may not be supported in the future. We are currently to writing big software in Julia and are little worried about this issue going forward. Any clarity would be greatly appreciated.
Assuming this is about the ABI changing version, #12205 has always been the easiest/trivial part of this. #21888 makes the GC frame allocation better but it is unrelated to this at all. As mentioned in other occasions, the current situation and the hardest part is described in great detail in #18632 . It covers most if not all of the known issues if we naively do this, most of which related to the fact that it can cause slow down in certain cases.
As for the non-ABI changing version of this, #21888 does make the gcframe allocation more efficient with a linear IR which in turn makes it easier to optimize if everything is inlined. Our optimization pass is actually smart enough to elide the allocation in many cases, just not all of them yet.
One of the downside of the (Array, Range)
trick is that it's not an AbstractArray
like a view, so one can't use inplace standard library APIs like sort!
on a view without allocating.
Since it will be some time before we can stack allocate views, would there interest in adding a range argument to some of the stdlib methods that take arrays. For example (the case I'm currently dealing with).
ar = rand(1000)
# Slow
sort!(view(ar, 100:200))
# Faster
sort!(ar, 100:200)
For consistency these methods could have the same signature as view, so that just views inside calls to stdlib functions that take an AbstractArray
should "just work".
(let me know if I should open a new issue).
My apologies, it seems this exists at least for a simple index range (but isn't referred to in the docs).
Line 464 in 0557467
Is there some sort of unsafe view
that one can use to circumvent this? I was looking at ArrayViews.jl
but it looks unmaintained (probably doesn't work in Julia 1.0).
UnsafeArrays.jl works well. The macro also uses @gcpreserve
so that using it is safe.
I'd be happy to get some feedback on UnsafeArrays.jl. :-)