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