JuliaArrays / JuliaArrays/StaticArrays.jl
broadcasts with assignment don't vectorize
Open
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 844
- Forks
- 159
- Avg merge
- 3d 21h
- Merged PRs (30d)
- 3
Description
I've tried out StaticArrays v1.9.13 with several processors (all amd64). Broadcasts without assignment vectorize. With assignment they don't, which means that they are much slower.
julia> v = zero(SVector{8,Int32}); w = MVector(v);
julia> @code_native debuginfo=:none v + w
; Function Signature: +(StaticArraysCore.SArray{Tuple{8}, Int32, 1, 8}, StaticArraysCore.MArray{Tuple{8}, Int32, 1, 8})
# %bb.0: # %top
#DEBUG_VALUE: +:a <- [DW_OP_deref] [$rsi+0]
push rbp
mov rbp, rsp
mov rax, rdi
#DEBUG_VALUE: +:b <- [DW_OP_deref] undef
#DEBUG_VALUE: +:b <- [DW_OP_deref] undef
vmovdqu ymm0, ymmword ptr [rsi]
vpaddd ymm0, ymm0, ymmword ptr [rdx]
vmovdqu ymmword ptr [rdi], ymm0
pop rbp
vzeroupper
ret
julia> f(v, w) = w .+= v;
julia> @code_native debuginfo=:none f(v, w)
; Function Signature: f(StaticArraysCore.SArray{Tuple{8}, Int32, 1, 8}, StaticArraysCore.MArray{Tuple{8}, Int32, 1, 8})
# %bb.0: # %top
#DEBUG_VALUE: f:v <- [DW_OP_deref] [$rdi+0]
push rbp
mov rbp, rsp
mov rax, rsi
#DEBUG_VALUE: f:w <- [DW_OP_deref] undef
#DEBUG_VALUE: f:w <- [DW_OP_deref] undef
mov ecx, dword ptr [rdi]
mov edx, dword ptr [rdi + 4]
mov esi, dword ptr [rdi + 8]
mov r8d, dword ptr [rdi + 12]
mov r9d, dword ptr [rdi + 16]
mov r10d, dword ptr [rdi + 20]
mov r11d, dword ptr [rdi + 24]
mov edi, dword ptr [rdi + 28]
add dword ptr [rax], ecx
add dword ptr [rax + 4], edx
add dword ptr [rax + 8], esi
add dword ptr [rax + 12], r8d
add dword ptr [rax + 16], r9d
add dword ptr [rax + 20], r10d
add dword ptr [rax + 24], r11d
add dword ptr [rax + 28], edi
pop rbp
ret
julia> g(v, w) = w .= v;
julia> @code_native debuginfo=:none g(v, w)
; Function Signature: g(StaticArraysCore.SArray{Tuple{8}, Int32, 1, 8}, StaticArraysCore.MArray{Tuple{8}, Int32, 1, 8})
# %bb.0: # %top
#DEBUG_VALUE: g:v <- [DW_OP_deref] [$rdi+0]
push rbp
mov rbp, rsp
mov rax, rsi
#DEBUG_VALUE: g:w <- [DW_OP_deref] undef
#DEBUG_VALUE: g:w <- [DW_OP_deref] undef
mov ecx, dword ptr [rdi]
mov dword ptr [rsi], ecx
mov ecx, dword ptr [rdi + 4]
mov dword ptr [rsi + 4], ecx
mov ecx, dword ptr [rdi + 8]
mov dword ptr [rsi + 8], ecx
mov ecx, dword ptr [rdi + 12]
mov dword ptr [rsi + 12], ecx
mov ecx, dword ptr [rdi + 16]
mov dword ptr [rsi + 16], ecx
mov ecx, dword ptr [rdi + 20]
mov dword ptr [rsi + 20], ecx
mov ecx, dword ptr [rdi + 24]
mov dword ptr [rsi + 24], ecx
mov ecx, dword ptr [rdi + 28]
mov dword ptr [rsi + 28], ecx
pop rbp
ret
Julia Version 1.11.4
Commit 8561cc3d68d (2025-03-10 11:36 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 4 × Intel(R) Core(TM) i3-10110U CPU @ 2.10GHz
WORD_SIZE: 64
LLVM: libLLVM-16.0.6 (ORCJIT, skylake)
Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No source file or test is named. Start by reproducing the Julia 1.11.4 examples with @code_native and compare broadcasts without assignment, w .+= v, and w .= v; done means assignment broadcasts for the shown StaticArrays case produce vectorized native code without changing their results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100