Julia alignas: is there a way to specify the alignment of Julia objects in memory?

You can allocate an Array using posix_memalign, for example:

function alignedvec(::Type{T}, n::Integer, alignment::Integer=sizeof(Int)) where {T}
    @static if Sys.iswindows()
        return Array{T}(undef, n)
    else
        ispow2(alignment) || throw(ArgumentError("$alignment is not a power of 2"))
        alignment ≥ sizeof(Int) || throw(ArgumentError("$alignment is not a multiple of $(sizeof(Int))"))
        isbitstype(T) || throw(ArgumentError("$T is not a bitstype"))
        p = Ref{Ptr{T}}()
        err = ccall(:posix_memalign, Cint, (Ref{Ptr{T}}, Csize_t, Csize_t), p, alignment, n*sizeof(T))
        iszero(err) || throw(OutOfMemoryError())
        return unsafe_wrap(Array, p[], n, own=true)
    end
end

but posix_memalign is unavailable on Windows so it has to fall back to unaligned memory in that case (Julia defaults to 16-byte alignment). If the alignment is just an optimization, however, that may not be so terrible.

It doesn’t seem crazy to add an alignment keyword argument to the Array constructor, but the difficulty of supporting Windows is (as usual) a pain point. (You can have an aligned-memory allocator on Windows, but then you can’t use free to deallocate it, and so you’d need lower-level hacks for garbage-collection to work.)

14 Likes