I just tried accessing `a[i]` out of bounds, while promising
`@inbounds` to Julia. Ideally, this would just work. Unfortunately,
Julia currently copies the argument `v` via a long sequence of move
instructions, making this (a) work but (b) inefficient.

-erik

On Sun, Mar 13, 2016 at 2:48 PM, Kristoffer Carlsson
<kcarlsso...@gmail.com> wrote:
> I would have hoped that this would generate the same code:
>
> immutable Foo{M, N, T}
> a::NTuple{M, T}
> b::NTuple{N, T}
> end
>
>
> immutable Foo2{N, T}
> a::NTuple{N, T}
> end
>
>
> @inline function gimmie{M, N, T}(v::Foo{M, N, T}, i)
> p = convert(Ptr{T}, pointer_from_objref(v))
> return unsafe_load(p, i)
> end
>
> @inline function gimmie{N, T}(v::Foo2{N, T}, i)
> @inbounds val = v.a[i]
> return val
> end
>
> @inline function gimmie{N, T}(v::NTuple{N, T}, i)
> @inbounds val = v[i]
> return val
> end
>
> a = Foo( (1.0,2.0), (3.0,4.0,5.0) )
> b = Foo2( (1.0,2.0,3.0,4.0,5.0) )
> c = ((1.0,2.0,3.0,4.0,5.0))
>
> @code_native gimmie(a, 1)
> @code_native gimmie(b, 1)
> @code_native gimmie(c, 1)
>
> But the code for Foo is more complicated. It includes calling for example
> jl_gc_allocobj.
>
> Do you know if there is a way to get a zero overhead access as compared to
> the one tuple version?
>
> On Sunday, March 13, 2016 at 3:42:18 PM UTC+1, Erik Schnetter wrote:
>>
>> Do you actually need a type declaration like this, or could you write
>> the equivalent of
>> ```Julia
>> immutable Foo2{M, N, T}
>>     ab::NTuple{M+N, T}
>> end
>> ```
>> and the introduce functions `geta` and getb` for `Foo`? This would be
>> a completely type-safe solution.
>>
>> On the other hand, if you are sure that the memory layout is as you
>> expect, you can always go the C way: Get a pointer to `Foo`,
>> unsafe-cast that pointer to `Foo2`, and access the elements via
>> `Foo2`.
>>
>> -erik
>>
>>
>> On Sun, Mar 13, 2016 at 7:57 AM, Kristoffer Carlsson
>> <kcarl...@gmail.com> wrote:
>> > Hello everyone.
>> >
>> > Assume I have an immutable like:
>> >
>> > immutable Foo{M, N, T}
>> >    a::NTuple{M, T}
>> >    b::NTuple{N, T}
>> > end
>> >
>> > and I want to make an efficient getindex into the tuple.
>> >
>> > Something that would probably be inefficient due to branching would be:
>> >
>> > function Base.getindex{M, N}(f::Foo({M,N}), i)
>> >     if i <= M
>> >        return f.a[i]
>> >     else
>> >        return f.b[i - N]
>> >     end
>> > end
>> >
>> > Is there anyway I can just grab the value at the address at an offset i
>> > - 1
>> > further forward of the address of f.a[1]. In my head this would be more
>> > efficient since it would be a very simple offset calculation. You can
>> > assume
>> > that T is a nice bits type like a Float32.
>> >
>> > Thanks!
>> >
>> > // Kristoffer
>> >
>> >
>> >
>> >
>>
>>
>>
>> --
>> Erik Schnetter <schn...@gmail.com>
>> http://www.perimeterinstitute.ca/personal/eschnetter/



-- 
Erik Schnetter <schnet...@gmail.com>
http://www.perimeterinstitute.ca/personal/eschnetter/

Reply via email to