Skip to content
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

Want non-allocating array views #14955

Closed
timholy opened this issue Feb 6, 2016 · 10 comments
Closed

Want non-allocating array views #14955

timholy opened this issue Feb 6, 2016 · 10 comments
Labels
performance Must go faster

Comments

@timholy
Copy link
Sponsor Member

timholy commented Feb 6, 2016

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.

@JeffBezanson
Copy link
Sponsor Member

I suppose all we need for this is e.g. #12205

@carnaval
Copy link
Contributor

#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 ?

@GravityAssisted
Copy link

GravityAssisted commented Jun 29, 2017

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.

@timholy
Copy link
Sponsor Member Author

timholy commented Jun 29, 2017

My understanding is that #21888 makes something like #12205 considerably easier than it once was. (But still work to do.)

@yuyichao
Copy link
Contributor

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.

@cshenton
Copy link

cshenton commented Apr 4, 2019

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).

@cshenton
Copy link

cshenton commented Apr 4, 2019

My apologies, it seems this exists at least for a simple index range (but isn't referred to in the docs).

function sort!(v::AbstractVector, lo::Int, hi::Int, ::InsertionSortAlg, o::Ordering)

@cossio
Copy link
Contributor

cossio commented Jun 23, 2019

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).

@chriselrod
Copy link
Contributor

UnsafeArrays.jl works well. The macro also uses @gcpreserve so that using it is safe.

@oschulz
Copy link
Contributor

oschulz commented Jul 4, 2019

I'd be happy to get some feedback on UnsafeArrays.jl. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Must go faster
Projects
None yet
Development

No branches or pull requests

10 participants