JuliaArrays / StructArrays.jl

Efficient implementation of struct arrays in Julia
https://juliaarrays.github.io/StructArrays.jl/
Other
332 stars 41 forks source link

Does this package facilitate SIMD optimizations? #96

Open cossio opened 5 years ago

cossio commented 5 years ago

I think SIMD optimizations are the main reason to use this package (but maybe there are more uses that I don't know about). In any case, SIMD is important. But it is not mentioned in the README.

If this package does facilitate SIMD optimizations, I think this should be mentioned in the README, with an example or two showing benchmarks. I'd really like to see some examples of this. And I think that if this is showcased, it would attract more users to the package.

cossio commented 5 years ago

Here is an example where StructArrays seems to facilitate SIMD optimization. (Relevant discussion about this example: https://discourse.julialang.org/t/struct-of-arrays-soa-vs-array-of-structs-aos/30015)

struct ComplexAoS
  real::Float64
  imag::Float64
end
struct ComplexSoA
  real::Vector{Float64}
  imag::Vector{Float64}
end

N = 1000
arrAoS = [ComplexAoS(rand(),rand()) for i in 1:N]
arrSoA = ComplexSoA(rand(N),rand(N))
s = StructArray(ComplexAoS(rand(),rand()) for i in 1:N)

function normSoA(x)
  out = 0.0
  @simd for i in 1:length(x.real)
    @inbounds out += sqrt(x.real[i]^2 + x.imag[i]^2)
  end
  out
end

function normAoS(x)
  out = 0.0
  @simd for i in 1:length(x)
    @inbounds out += sqrt(x[i].real^2 + x[i].imag^2)
  end
  out
end

julia> using BenchmarkTools

julia> @btime normAoS($arrAoS);
  2.076 μs (0 allocations: 0 bytes)

julia> @btime normSoA($arrSoA);
  1.142 μs (0 allocations: 0 bytes)

julia> @btime normSoA($s);
  1.229 μs (0 allocations: 0 bytes)

I suggest something like this me added to the README. Or at least that the README mentions explicitly how this package facilitates SIMD optimizations.

Maybe someone more knowledgeable can also inspect the resulting @code_llvm and check that the SIMD calls are in fact being exploited thanks to StructArrays.