Это прямая перезапись вашего цикла, которая поддерживает потоки и предотвращает ложное совместное использование:
using Random
using Base.Threads
V = let
mt = Tuple([MersenneTwister() for _ in 1:nthreads()])
Vv = Tuple([zeros(3) for _ in 1:nthreads()])
@threads for i = 1:100000
@inbounds cc = rand(mt[threadid()], 1:3)
@inbounds Vv[threadid()][cc] += 1
end
reduce(+, Vv)
end
Тем не менее, в общем случае для такой небольшой работы, вероятно, использование потоков не принесет вам большой пользы. ,Кроме того, если вам действительно нужна производительность, возможно, код должен быть немного реструктурирован, например, так:
function worker(iters, rng)
v = zeros(3)
for i = 1:iters
cc = rand(rng, 1:3)
v[cc] += 1
end
v
end
V = let
mt = Tuple([MersenneTwister() for _ in 1:nthreads()])
Vv = [zeros(3) for _ in 1:nthreads()]
jobs_per_thread = fill(div(100000, nthreads()),nthreads())
for i in 1:100000-sum(jobs_per_thread)
jobs_per_thread[i] += 1
end
@assert sum(jobs_per_thread) == 100000
@threads for i = 1:nthreads()
Vv[threadid()] = worker(jobs_per_thread[threadid()], mt[threadid()])
end
reduce(+, Vv)
end
Также в Julia 1.3 вам не придется выполнять ручное MersenneTwister
управление, так как Julia создаст отдельный PRNG длянить.