Julia: المجموع | mapreduce مقابل حلقة for unrolled. تفاوت الأداء

تم إنشاؤها على ٨ فبراير ٢٠١٧  ·  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)))

يعطيني نسبة أداء تبلغ حوالي x50 على Julia 0.5 ، juliabox.com. أعتقد أن هذا قد يكون لأن الحلقة for يمكن أن تكون تلقائيًا simd ، و mapreduce ليس كذلك؟ عندما يكون 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. هل سيكون هذا معيارًا مفيدًا؟ على nanosoldier؟
  4. هل يمكن أن تكون فجوة الأداء أصغر؟

(قياس الأداء mapreduce مقابل for -loops بدون وصول إلى المصفوفة ، ما زلت أرى فجوة في الأداء x2. على سبيل المثال ، mapreduce(identity, +, 0, i for i in 1:n) مقابل جمع عدد صحيح مكافئ for حلقة. يبدو أن هذه الفجوة كانت أصغر في السابق؟ هل تستحق معيارًا آخر في CI؟)

performance

التعليق الأكثر فائدة

+1 لوضع معيار لهذا في BaseBenchmarks ؛ العلاقات العامة سيكون هناك عظيم.

ال 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 لوضع معيار لهذا في BaseBenchmarks ؛ العلاقات العامة سيكون هناك عظيم.

الإغلاق كوجه مزدوج رقم 15276.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات