Problem wielowątkowy w Julii

Aug 18 2020

Próbuję zrównoleglać niektóre bity kodu, ale nie rozumiem, dlaczego następujące funkcje main1 () i main2 () dają różne wyniki przy użyciu wielowątkowości Julii:

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

Jak można poprawnie naprawić zrównoleglenie funkcji main1 ()?

Odpowiedzi

1 PrzemyslawSzufel Aug 18 2020 at 23:44

Nie można zagnieżdżać @threadspętli, więc zwykle należy:

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

Jednak w swoim kodzie otrzymujesz tę samą icwartość dla różnych par wartości (i,j). W main1jesteś nadpisywania te same części L, FF, FTwiele razy, co jest oczywistym błędem. Wielowątkowość zmieni kolejność nadpisywania danych, więc przyniesie różne wyniki. Podsumowując, najpierw napraw, main1a następnie zrównoleglaj to.