That does seem to be the issue. It's tricky to fix since you can't evaluate
sizeof(Ptr) unless the condition is true.

On Tue, Mar 24, 2015 at 7:13 PM, Stefan Karpinski <[email protected]>
wrote:

> There's a branch in eltype, which is probably causing this difference.
>
> On Tue, Mar 24, 2015 at 7:00 PM, Sebastian Good <
> [email protected]> 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 ([email protected]) 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 <[email protected]>
>>> 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