StaticArrays.jl icon indicating copy to clipboard operation
StaticArrays.jl copied to clipboard

Performance bug in compiling functions

Open laurentbartholdi opened this issue 4 years ago • 3 comments

With Julia 1.7 and the StaticArrays v0.12.5:

julia> N = 14; m = SMatrix{N,N}(rand(N,N));

julia> x->x*m # works fine
#1 (generic function with 1 method)

julia> @time [x->x*g for g∈[m]]
  3.018892 seconds (57.49 k allocations: 3.383 MiB, 100.06% compilation time)
1-element Vector{var"#20#22"{SMatrix{14, 14, Float64, 196}}}:
 #20 (generic function with 1 method)

Why does it take 3 seconds? It seems to scale horribly, too: for N=10, I get 0.449260 seconds; for N=15, 5.230108 seconds; for N=16, 9.209356 seconds.

laurentbartholdi avatar Jul 17 '21 13:07 laurentbartholdi

StaticArrays.jl isn't generally designed to work with such arrays. Very few operations on StaticArrays with more than 100 elements are faster than their non-statically sized counterparts. Of course it's possible to quickly generate code that would perform similarly to builtin functions but on StaticArrays, although it's a relatively complex task and just using normal arrays is a very easy workaround.

By the way, is there a specific reason why you still use the 0.12.5 version instead of newer ones? They have some improvements to matrix multiplication.

mateuszbaran avatar Jul 17 '21 14:07 mateuszbaran

OK, I get it that StaticArrays is not designed for this use. However, I can't see what takes 3 seconds, when the type SMatrix{14,14} has already been compiled. Worse than that, repeating the line [x->xg for g∈[m]] N times takes N3 seconds; so some types are recreated mysteriously.

On Sat, Jul 17, 2021 at 4:26 PM Mateusz Baran @.***> wrote:

StaticArrays.jl isn't generally designed to work with such arrays. Very few operations on StaticArrays with more than 100 elements are faster than their non-statically sized counterparts. Of course it's possible to quickly generate code that would perform similarly to builtin functions but on StaticArrays, although it's a relatively complex task and just using normal arrays is a very easy workaround.

By the way, is there a specific reason why you still use the 0.12.5 version instead of newer ones? They have some improvements to matrix multiplication.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/JuliaArrays/StaticArrays.jl/issues/937#issuecomment-881907234, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARAQUC3WUOBK4CQBHADWHTTYGHJTANCNFSM5ARCVUWA .

-- Laurent Bartholdi laurent.bartholdigmailcom Mathematisches Institut, Georg-August Universität zu Göttingen Bunsenstrasse 3-5, D-37073 Göttingen, Germany

laurentbartholdi avatar Jul 18 '21 11:07 laurentbartholdi

Note that [x->x*g for g∈[m]] doesn't actually do any multiplication by itself, it makes a Vector of anonymous functions. Also repeating this line creates new anonymous functions that must be handled separately. I've checked on StaticArrays 1.2.6 and the entire multiplication code gets separately inlined into each anonymous function which means that very little (if anything) can be cached here.

Also, to my knowledge, there is no such thing as a type being compiled -- specific methods are compiled for specific argument types (either concrete of abstract supertypes depending on a few factors).

mateuszbaran avatar Jul 18 '21 12:07 mateuszbaran