I’ve been experimenting with the @sync
and @async
macros and I need some advice.
Basically, I have some (nested) embarrassingly parallel loops. The issue is, I want to store the calculations from each function call asynchronously. But I’m having some trouble on the storing part.
The following code should exemplify this:
function sleep_ij(i,j)
res = i^2+j
sleep(0.1*res)
return res
end
@time begin
res = Vector{Float64}(undef, 5)
res_arr = fill(res, 2)
@sync for i in 1:2
@async res_arr[i] = [sleep_ij(i,j) for j in 1:5]
end
println(res_arr)
end
# Slow but correct results
# Array{Float64,1}[[2.0, 3.0, 4.0, 5.0, 6.0], [5.0, 6.0, 7.0, 8.0, 9.0]]
# 3.577137 seconds (122.19 k allocations: 6.380 MiB)
@time begin
res = Vector{Float64}(undef, 5)
res_arr = fill(res, 2)
@sync for i in 1:2
for j in 1:5
@async res_arr[i][j] = sleep_ij(i,j)
end
end
println(res_arr)
end
# Fast but wrong results
# Array{Float64,1}[[5.0, 6.0, 7.0, 8.0, 9.0], [5.0, 6.0, 7.0, 8.0, 9.0]]
# 0.912431 seconds (12.53 k allocations: 698.873 KiB)
@time begin
res_arr = []
@sync for i in 1:2
for j in 1:5
@async push!(res_arr, sleep_ij(i,j))
end
end
println(res_arr)
end
# Fast but won't keep order (which is a must)
# Any[2, 3, 4, 5, 5, 6, 6, 7, 8, 9]
# 0.910911 seconds (12.21 k allocations: 684.984 KiB)
Is there any way I can achieve the fastest speeds shown above and at the same time fill my resulting array with the correct values?