Вы не предоставили минимальный рабочий пример, но я думаю, что это может быть сложно.Так вот мой MWE.Предположим, что мы хотим использовать Distributed
для вычисления сумм столбцов Array
:
using Distributed
addprocs(2)
@everywhere using StatsBase
data = rand(1000,2000)
res = zeros(2000)
@sync @distributed for col = 1:size(data)[2]
res[col] = StatsBase.mean(data[:,col])
# does not work!
# ... because data is created locally and never returned!
end
Чтобы исправить вышеприведенный код, вам нужно предоставить функцию-агрегатор (я продолжаю примернамеренно упрощено - возможна дальнейшая оптимизация).
using Distributed
addprocs(2)
@everywhere using Distributed,StatsBase
data = rand(1000,2000)
@everywhere function t2(d1,d2)
append!(d1,d2)
d1
end
res = @sync @distributed (t2) for col = 1:size(data)[2]
[(myid(),col, StatsBase.mean(data[:,col]))]
end
Теперь давайте посмотрим на результат.Мы можем видеть, что некоторые значения были рассчитаны на работника 2
, а другие на работника 3
:
julia> res
2000-element Array{Tuple{Int64,Int64,Float64},1}:
(2, 1, 0.49703681326230276)
(2, 2, 0.5035341367791002)
(2, 3, 0.5050607022354537)
⋮
(3, 1998, 0.4975699181976122)
(3, 1999, 0.5009498778934444)
(3, 2000, 0.499671315490524)
Дальнейшие возможные улучшения / модификации:
- использование
@spawnat
для генерации значений в удаленных процессах (вместо основного процесса и их отправки) - use
SharedArray
- это позволяет автоматически распределять данные между работниками.Из моего опыта требуется очень тщательное программирование. - Использование
ParallelDataTransfer.jl
для отправки данных среди рабочих.Очень прост в использовании, неэффективен для огромного количества сообщений. - всегда учитывайте механизм потоков Юлии (в некоторых случаях это облегчает жизнь - опять же зависит от проблемы)