There's a branch in eltype, which is probably causing this difference.

On Tue, Mar 24, 2015 at 7:00 PM, Sebastian Good <
sebast...@palladiumconsulting.com> wrote:

> Yep, that’s done it. The only difference I can see in the code I wrote
> before and this code is that previously I had
>
> convert(Ptr{T}, pointer(raw, byte_number))
>
> whereas here we have
>
> convert(Ptr{T}, pointer(raw) + byte_number - 1)
>
> The former construction seems to emit a call to a Julia-intrinsic
> function, while the latter executes the more expected simple machine loads.
> Is there a subtle difference between the two calls to pointer?
>
> Thanks all for your help!
>
> On March 24, 2015 at 12:19:00 PM, Matt Bauman (mbau...@gmail.com) wrote:
>
> (The key is to ensure that the method gets specialized for different types
> with the parametric `::Type{T}` in the signature instead of
> `T::DataType`).
>
> On Tuesday, March 24, 2015 at 12:10:59 PM UTC-4, Stefan Karpinski wrote:
>>
>> This seems like it works fine to me (on both 0.3 and 0.4):
>>
>>  immutable Test
>> x::Float32
>> y::Int64
>> z::Int8
>> end
>>
>>  julia> a = [Test(1,2,3)]
>> 1-element Array{Test,1}:
>>  Test(1.0f0,2,3)
>>
>> julia> b = copy(reinterpret(UInt8, a))
>> 24-element Array{UInt8,1}:
>>  0x00
>>  0x00
>>  0x80
>>  0x3f
>>  0x03
>>  0x00
>>  0x00
>>  0x00
>>  0x02
>>  0x00
>>  0x00
>>  0x00
>>  0x00
>>  0x00
>>  0x00
>>  0x00
>>  0x03
>>  0xe0
>>  0x82
>>  0x10
>>  0x01
>>  0x00
>>  0x00
>>  0x00
>>
>> julia> prim_read{T}(::Type{T}, data::Array{Uint8,1}, offset::Int) =
>> unsafe_load(convert(Ptr{T}, pointer(data) + offset))
>> prim_read (generic function with 1 method)
>>
>> julia> prim_read(Test, b, 0)
>> Test(1.0f0,2,3)
>>
>> julia> @code_native prim_read(Test, b, 0)
>> .section __TEXT,__text,regular,pure_instructions
>> Filename: none
>> Source line: 1
>> push RBP
>> mov RBP, RSP
>> Source line: 1
>> mov RCX, QWORD PTR [RSI + 8]
>> vmovss XMM0, DWORD PTR [RCX + RDX]
>> mov RAX, QWORD PTR [RCX + RDX + 8]
>> mov DL, BYTE PTR [RCX + RDX + 16]
>> pop RBP
>> ret
>>
>>
>> On Tue, Mar 24, 2015 at 5:04 PM, Simon Danisch <sdan...@gmail.com> wrote:
>>
>>> There is a high chance that I simply don't understand llvmcall well
>>> enough, though ;)
>>>
>>> Am Montag, 23. März 2015 20:20:09 UTC+1 schrieb Sebastian Good:
>>>>
>>>> I'm trying to read some binary formatted data. In C, I would define an
>>>> appropriately padded struct and cast away. Is is possible to do something
>>>> similar in Julia, though for only one value at a time? Philosophically, I'd
>>>> like to approximate the following, for some simple bittypes T (Int32,
>>>> Float32, etc.)
>>>>
>>>> T read<T>(char* data, size_t offset) { return *(T*)(data + offset); }
>>>>
>>>> The transliteration of this brain-dead approach results in the
>>>> following, which seems to allocate a boxed Pointer object on every
>>>> invocation. The pointer function comes with ample warnings about how it
>>>> shouldn't be used, and I imagine that it's not polite to the garbage
>>>> collector.
>>>>
>>>>  prim_read{T}(::Type{T}, data::AbstractArray{Uint8, 1}, byte_number) =
>>>> unsafe_load(convert(Ptr{T}, pointer(data, byte_number)))
>>>>
>>>> I can reinterpret the whole array, but this will involve a division of
>>>> the offset to calculate the new offset relative to the reinterpreted array,
>>>> and it allocates an array object.
>>>>
>>>> Is there a better way to simply read the machine word at a particular
>>>> offset in a byte array? I would think it should inline to a single assembly
>>>> instruction if done right.
>>>>
>>>>
>>>
>>

Reply via email to