Problème de multi-threading dans Julia
J'essaie de paralléliser certains bits d'un code mais je ne comprends pas pourquoi les fonctions suivantes main1 () et main2 () donnent des résultats différents en utilisant le multi-threading de 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
Comment la parallélisation de main1 () pourrait-elle être correctement corrigée?
Réponses
Vous ne pouvez pas imbriquer les @threads
boucles, vous devriez donc normalement faire:
Threads.@threads for u in vec(CartesianIndices((4,4)))
i,j = u.I
# your code goes here
end
Cependant, dans votre code, vous obtenez la même ic
valeur pour différentes paires de valeurs de (i,j)
. Dans le main1
vous écrasez les mêmes parties L
, FF
, à FT
plusieurs reprises ce qui est un bug évident. Le multi-threading changera l'ordre dans lequel les données sont écrasées et produira donc des résultats différents. En conclusion, corrigez d'abord main1
et parallélisez-le.