Julia: рдпреЛрдЧ | рдореИрдкреНрд░реЗрдбреНрдпреВрд╕ рдмрдирд╛рдо рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдлреЙрд░-рд▓реВрдкред рдкреНрд░рджрд░реНрд╢рди рдЕрд╕рдорд╛рдирддрд╛

рдХреЛ рдирд┐рд░реНрдорд┐рдд 8 рдлрд╝рд░ре░ 2017  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: JuliaLang/julia

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 рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

  1. рдХреНрдпрд╛ simd рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдХреЛрдИ x50 рддреЗрдЬ рд╣реИ?
  2. рдХреНрдпрд╛ рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдпреБрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП? mapreduce рдХреЗ рдЕрдВрддрд░реНрдЧрдд sum рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдЬрд╛рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
  3. рдХреНрдпрд╛ рдпрд╣ рдПрдХ рдЙрдкрдпреЛрдЧреА рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд╣реЛрдЧрд╛? рдиреИрдиреЛ рд╕реИрдирд┐рдХ рдкрд░?
  4. рдХреНрдпрд╛ рдкреНрд░рджрд░реНрд╢рди рдЕрдВрддрд░ рдЫреЛрдЯрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?

(рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ mapreduce рдмрдирд╛рдо for - рдмрд┐рдирд╛ рд╕рд░рдгреА рдкрд╣реБрдВрдЪ рдХреЗ рд▓реВрдк, рдореБрдЭреЗ рдЕрднреА рднреА рдПрдХ x2 рдкреНрд░рджрд░реНрд╢рди рдЕрдВрддрд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ mapreduce(identity, +, 0, i for i in 1:n) рдмрдирд╛рдо рд╕рдорддреБрд▓реНрдп рдкреВрд░реНрдгрд╛рдВрдХ-рдпреЛрдЧ for рд▓реВрдкред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдВрддрд░ рдЫреЛрдЯрд╛ рд╣реБрдЖ рдХрд░рддрд╛ рдерд╛? рд╕реАрдЖрдИ рдореЗрдВ рдПрдХ рдФрд░ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЗ рд▓рд╛рдпрдХ?)

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдмреЗрд╕рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдореЗрдВ рдЗрд╕рдХрд╛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП +1; рдПрдХ рдЬрдирд╕рдВрдкрд░реНрдХ рд╡рд╣рд╛рдБ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред

рд╕рднреА 3 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

https://github.com/JuliaLang/julia/issues/15276 рдХрд╛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред

рдХрд░рддреЗ рд╣реБрдП:

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 рдХреЗ рдбреБрдкреНрд▓реАрдХреЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдорд╛рдкрдиред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕