function calculate(i)
# do something, maybe expensive
return eye(2)*rand()
end
s = zeros(2, 2)
Thread.@thread for i in 1:100
s += calculate(i)
end
I understand this program is not thread-safe since multiple threads may be accessing s at the same time. However, since the document of multithreading is very short. I don’t know how to fix the problem. Anyone offer some help?
function calculate(i)
return sin(i)
end
s = zeros(Threads.nthreads())
Threads.@threads for i in 1:10^6
s[Threads.threadid()] += calculate(i)
end
sum(s)
each thread write to their own part and then you do a serial reduction in the end.
Thank you. This definitely works. However, this solution is effectively storing everything calculate returns, which costs a lot of memory in my case. Is there anything like lock and unlock?
function calculate(i)
# do something, maybe expensive
return eye(2)*rand()
end
s = zeros(2, 2)
mutex = Threads.Mutex()
Thread.@thread for i in 1:100
Threads.lock(mutex)
s += calculate(i)
Threads.unlock(mutex)
end
That would have terrible performance, since all threads are waiting and only one is working at any one time, so it’s a single-thread working disguised in multi-threading. If calculate is taken out of the lock and is really expensive then it will be better, but then the intermediate still needs to be stored, so you might as well avoid waiting altogether and use Kristoffer’s solution.
Edit: if it was just a demo of locks, then I may have over-reacted
Multithreading is new to me. A simple question: If I do
function calculate(i)
# do something, maybe expensive
return eye(2)*rand()
end
s = zeros(2, 2)
mutex = Threads.Mutex()
Thread.@thread for i in 1:100
result = calculate(i)
Threads.lock(mutex)
s += result
Threads.unlock(mutex)
end
Will there be any conflicts for name bindings of result?
Interesting, this is an issue I haven’t personally ran into. I’ve been doing excessive amounts of matrix multiplications inside loops, but probably not exactly in the way that the issue states. I guess just avoid this situation?
Maybe. Although I cannot identify the situation confidently and I need to do quite a lot of things inside calculate. Maybe that’s why multithreading is labeled as experimental in the document.