Problema di multi-threading in Julia

Aug 18 2020

Sto cercando di parallelizzare alcuni bit di un codice ma non capisco perché le seguenti funzioni main1 () e main2 () danno risultati diversi usando il multi-threading di Julia:

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

Come potrebbe essere corretta la parallelizzazione di main1 ()?

Risposte

1 PrzemyslawSzufel Aug 18 2020 at 23:44

Non puoi annidare i @threadsloop quindi normalmente dovresti fare:

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

Tuttavia, nel codice si ottiene lo stesso icvalore per diverse coppie di valori di (i,j). Nella main1si sta sovrascrivendo le stesse parti del L, FF, FTmolte volte che è un bug evidente. Il multi-threading cambierà l'ordine in cui i dati vengono sovrascritti in modo da produrre risultati diversi. In conclusione, prima aggiustalo main1e poi parallelizzalo.