# Parellel arrays

I need to have multiple threads write values to a shared array. I’m thinking of having each thread write to a private array, and then have the threads each write their private values into a shared array. In the following example I’ve chosen values that assume 2 threads, and I’m assuming thread 1 has written the values 1 and 2, and thread 2 has written the values 3, 4, 5. A prefix sum is used to let each thread know where to start writing in the shared array (`b`).

``````using Base.Threads

function copyVerts!(b, subarray, start, nper, id)
for i in 1:nper[id]
b[start[id]+i] = subarray[id][i]
end
end

b = Array{Int64,1}(undef,5)
subarray = [1,2]
subarray = [3,4,5]
nper = [2,3]  # thread 1 has 2 values and thread 2 has 3 values
start = cumsum(nper) - nper # exclusive prefix sum
Threads.@spawn copyVerts!(b, subarray, start, nper, i)
end
``````

This gives:

``````julia> b
5-element Array{Int64,1}:
1
2
3
4
5
``````

Is this a good solution, and how do I wait for all tasks to complete? Feedback would be appreciated.

Just playing around with your idea I came up with the following:

``````using .Threads

function copyVerts!(b, sub, start)
for i in 1:length(sub)
b[start + i - 1] = sub[i]
end
end

s2 = s1 .+ 1
c1 = cumsum(s1)
c2 = cumsum(s2)
sa = [c1[i]:c2[i] for i in s1]
b = zeros(Int,maximum(c2))

end
``````

then with

``````julia> nthreads()
8

julia> show(sa)
UnitRange{Int64}[1:2, 3:5, 6:9, 10:14, 15:20, 21:27, 28:35, 36:44]
julia> show(b)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]
``````

Thanks! It looks basically the same as mine, although I think your `copyVerts` function is better than mine since you’re taking out reference to the thread index, so you don’t have my indirect indexing (`b[start[id]+i]`). I used an array of subarrays since I don’t know how long each subarray will be and may have to resize. My example happened to have consecutive integers as the final result, but the final result could have any values.

If the code were to continue past the `for` loop, how can one wait until all the spawned tasks have completed?

If the code were to continue past the `for` loop, how can one wait until all the spawned tasks have completed?

`@sync`.

1 Like

the `@sync` does this.

1 Like