Проблема с многопоточностью в Julia

Aug 18 2020

Я пытаюсь распараллелить некоторые фрагменты кода, но не понимаю, почему следующие функции main1 () и main2 () дают разные результаты с использованием многопоточности Джулии:

a = rand(4,4);b = rand(4,4);c = rand(4,4);d = rand(4,4)

function main1(a,b,c,d)
    L = zeros(2,2,16)
    FF = zeros(2,2,16)
    FT = zeros(2,2,16)
    F = Array{Float32}(undef,2,2)
    # L = Array{Array{Float32, 1}, 4}

    for i = 1:4
        for j = 1:4
            ic = i + j*(i-1)
            F[1,1] = a[i,j]
            F[1,2] = b[i,j]
            F[2,1] = c[i,j]
            F[2,2] = d[i,j]
            L[:,:,ic] .= F * F'
            FF[:,:,ic] .= F
            FT[:,:,ic] .= F'
        end
    end
    return L,FF,FT
end

function main2(a,b,c,d)

    L  = zeros(2,2,16)
    FF = zeros(2,2,16)
    FT = zeros(2,2,16)
    F  = Array{Float32}(undef,2,2)
    # L = Array{Array{Float32, 1}, 4}

    Threads.@threads for i = 1:4
        Threads.@threads for j = 1:4
            ic = i + j*(i-1)
            F[1,1] = a[i,j]
            F[1,2] = b[i,j]
            F[2,1] = c[i,j]
            F[2,2] = d[i,j]
            L[:,:,ic] .= F * F'
            FF[:,:,ic] .= F
            FT[:,:,ic] .= F'
        end
    end
    return L,FF,FT
end

Как правильно исправить распараллеливание main1 ()?

Ответы

1 PrzemyslawSzufel Aug 18 2020 at 23:44

Вы не можете вкладывать @threadsциклы, поэтому обычно вы должны сделать:

Threads.@threads for u in vec(CartesianIndices((4,4)))
    i,j = u.I
    # your code goes here
end

Однако в вашем коде вы получаете одно и то же icзначение для разных пар значений (i,j). В main1перезаписи одни и те же части L, FF, FTмного раз , что является очевидной ошибкой. Многопоточность изменит порядок перезаписи данных, поэтому результаты будут разными. В заключение, сначала исправьте, main1а затем распараллелите.