mapreduce
рдмрд░рд╛рдмрд░ for
-рд▓реВрдк рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдзреАрдорд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рдЫреЛрдЯрд╛ ( рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди ) рдЙрджрд╛рд╣рд░рдг:
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)))
рдореБрдЭреЗ рдЬреВрд▓рд┐рдпрд╛ 0.5, juliabox.com рдкрд░ рд▓рдЧрднрдЧ x50 рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдЕрдиреБрдкрд╛рдд рджреЗрддрд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ for
-рд▓реВрдк рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ simd
рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдореИрдкреНрд░рд┐рдбрд╕ рдирд╣реАрдВ рд╣реИ? рдЬрдм A = randn(N,N)
рдФрд░ N
16
рд╣реИ, рддреЛ рдЕрдВрддрд░ x75 рдХреЗ рдЖрд╕рдкрд╛рд╕ рд╣реИ, рдФрд░ N = 10000
рдХреЗ рд▓рд┐рдП, рдЕрдВрддрд░ рд▓рдЧрднрдЧ x25 рд╣реИред рдРрд░реЗ рдПрдХреНрд╕реЗрд╕ A[j,k]
рдХреЛ A[rand(1:size(A,1)),rand(1:size(A,2))]
рд╕реЗ рдмрджрд▓рдиреЗ рд╕реЗ рджреЛрдиреЛрдВ рдкрд░ рдкреНрд░рджрд░реНрд╢рди рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдиреБрдкрд╛рдд X1 рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
simd
рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдХреЛрдИ x50 рддреЗрдЬ рд╣реИ?mapreduce
рдХреЗ рдЕрдВрддрд░реНрдЧрдд sum
рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдЬрд╛рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ(рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ mapreduce
рдмрдирд╛рдо for
- рдмрд┐рдирд╛ рд╕рд░рдгреА рдкрд╣реБрдВрдЪ рдХреЗ рд▓реВрдк, рдореБрдЭреЗ рдЕрднреА рднреА рдПрдХ x2 рдкреНрд░рджрд░реНрд╢рди рдЕрдВрддрд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ mapreduce(identity, +, 0, i for i in 1:n)
рдмрдирд╛рдо рд╕рдорддреБрд▓реНрдп рдкреВрд░реНрдгрд╛рдВрдХ-рдпреЛрдЧ for
рд▓реВрдкред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдВрддрд░ рдЫреЛрдЯрд╛ рд╣реБрдЖ рдХрд░рддрд╛ рдерд╛? рд╕реАрдЖрдИ рдореЗрдВ рдПрдХ рдФрд░ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЗ рд▓рд╛рдпрдХ?)
рдХрд░рддреЗ рд╣реБрдП:
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)
рджреЗрддрд╛ рд╣реИ
julia> time(median(<strong i="12">@benchmark</strong> dsum(A)))/time(median(<strong i="13">@benchmark</strong> dfor(A)))
1.0013213312412255
рдЖрдк рд╕рдорд╕реНрдпрд╛ рдХреЛ @code_warntype
рджреНрд╡рд╛рд░рд╛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ Core.Box
рдХреА рддрд▓рд╛рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдмреЗрд╕рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдореЗрдВ рдЗрд╕рдХрд╛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП +1; рдПрдХ рдЬрдирд╕рдВрдкрд░реНрдХ рд╡рд╣рд╛рдБ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред
#15276 рдХреЗ рдбреБрдкреНрд▓реАрдХреЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдорд╛рдкрдиред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдмреЗрд╕рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдореЗрдВ рдЗрд╕рдХрд╛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП +1; рдПрдХ рдЬрдирд╕рдВрдкрд░реНрдХ рд╡рд╣рд╛рдБ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред