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