mapreduce
kann viel langsamer sein als die äquivalente for
-Schleife. Ein kleines ( reales ) Beispiel:
function dsum(A::Matrix)
z = zero(A[1,1])
n = Base.LinAlg.checksquare(A)
B = Vector{typeof(z)}(n)
<strong i="9">@inbounds</strong> for j in 1:n
B[j] = mapreduce(k -> A[j,k]*A[k,j], +, z, 1:j)
end
B
end
function dfor(A::Matrix)
z = zero(A[1,1])
n = Base.LinAlg.checksquare(A)
B = Vector{typeof(z)}(n)
<strong i="10">@inbounds</strong> for j in 1:n
d = z
for k in 1:j
d += A[j,k]*A[k,j]
end
B[j] = d
end
B
end
A = randn(127,127)
time(median(<strong i="11">@benchmark</strong> dsum(A)))/time(median(<strong i="12">@benchmark</strong> dfor(A)))
gibt mir ein Leistungsverhältnis von etwa x50 auf Julia 0,5, juliabox.com. Ich denke, das könnte daran liegen, dass die for
-Schleife automatisch simd
sein kann und die MapReduce nicht? Wenn A = randn(N,N)
und N
gleich 16
sind, beträgt die Lücke etwa x75, und für N = 10000
beträgt die Lücke etwa x25. Das Ersetzen des Array-Zugriffs A[j,k]
durch A[rand(1:size(A,1)),rand(1:size(A,2))]
zerstört die Leistung auf beiden, aber das Verhältnis wird x1.
simd
der Grund, warum man x50 schneller ist?mapreduce
liegt sum
zugrunde, daher könnte dies eine beliebte Falle sein, die derzeit nicht erwähnt wird(Beim Benchmarking mapreduce
versus for
-Loops ohne Array-Zugriff sehe ich immer noch eine x2-Leistungslücke. ZB mapreduce(identity, +, 0, i for i in 1:n)
gegenüber der äquivalenten ganzzahlsummierenden for
-Schleife. Es sieht so aus, als wäre diese Lücke früher kleiner gewesen - einen weiteren Benchmark in CI wert?)
Sieht aus wie ein Dup von https://github.com/JuliaLang/julia/issues/15276.
Tun:
function dsum(A::Matrix)
z = zero(A[1,1])
n = Base.LinAlg.checksquare(A)
B = Vector{typeof(z)}(n)
<strong i="8">@inbounds</strong> for j::Int in 1:n
B[j] = _help(A, j, z)
end
B
end
_help(A, j, z) = mapreduce(k -> A[j,k]*A[k,j], +, z, 1:j)
gibt
julia> time(median(<strong i="12">@benchmark</strong> dsum(A)))/time(median(<strong i="13">@benchmark</strong> dfor(A)))
1.0013213312412255
Sie können das Problem sehen, indem Sie @code_warntype
suchen und nach Core.Box
suchen.
+1 für das Setzen eines Benchmarks davon in BaseBenchmarks; eine PR wäre toll.
Schließt als Dup von #15276.
Hilfreichster Kommentar
+1 für das Setzen eines Benchmarks davon in BaseBenchmarks; eine PR wäre toll.