Время, проведенное в резьбовом цикле, ничтожно мало по сравнению с остальными операциями. Вы также выделяете массивы с размером, зависящим от количества потоков, поэтому при использовании нескольких потоков вы тратите даже (немного) больше времени на выделение памяти.
Пожалуйста, посмотрите на https://docs.julialang.org/en/v1/manual/performance-tips/, если вы заботитесь о производительности. В частности, любой ценой избегайте глобальных переменных (они снижают производительность) и помещайте все в функции, которые также легче тестировать и отлаживать. Например, я переписал ваш код как:
using Random
using Base.Threads
function bin(id, Njobs, x, y, z, w)
dr = 1
bin_array = zeros(10)
for i in (id-1)*Njobs + 1:id*Njobs
r = sqrt(x[i]^2 + y[i]^2 + z[i]^2)
i_bin = floor(Int, r/dr) + 1
if i_bin < 10
bin_array[i_bin] += w[i]
end
end
bin_array
end
function test()
Ngal = 100000000
x = rand(Ngal)*5
y = rand(Ngal)*5
z = rand(Ngal)*5
w = ones(Ngal)
Nthreads = nthreads()
VV = [zeros(10) for _ in 1:Nthreads]
jobs_per_thread = fill(div(Ngal, Nthreads),Nthreads)
for i in 1:Ngal-sum(jobs_per_thread)
jobs_per_thread[i] += 1
end
@threads for i = 1:Nthreads
tid = threadid()
VV[tid] = bin(tid, jobs_per_thread[tid], x, y, z, w)
end
reduce(+, VV)
end
test()
Производительность с одним потоком:
julia> @time test();
3.054144 seconds (33 allocations: 5.215 GiB, 11.03% gc time)
Производительность с 4 потоками:
julia> @time test();
2.602698 seconds (65 allocations: 5.215 GiB, 9.92% gc time)
Если я прокомментирую for
цикл в test()
Я получаю следующие сроки. Одна нить:
julia> @time test();
2.444296 seconds (21 allocations: 5.215 GiB, 10.54% gc time)
4 темы:
julia> @time test();
2.481054 seconds (27 allocations: 5.215 GiB, 12.08% gc time)