Julia 语言通过 pmat() 和 @parallel 等方法支持并行化。
我正在尝试计算一组数据的相异矩阵:
n = length(dataset)
mat = zeros(n,n)
for i = 1 : n
for j = i+1 : n
mat[i,j] = mat[j,i] = f_dist(dataset[i], dataset[j])
end
end
由于计算是独立的,我认为这应该是并行计算的一个很好的候选者。
我尝试使用 pmat() 和 @parallel 最终都变慢了。
mat = @parallel (+) for comb in collect(combinations([1:n],2))
submat = zeros(n,n)
i = comb[1]
j = comb[2]
dist = f_dist(dataset[i],dataset[j])
submat[i,j] = dist
submat[j,i] = dist
submat
end
我知道@parallel 是一个糟糕的方法,因为我实际上是在创建一堆稀疏矩阵并将它们加在一起。非常低效。
有没有一种有效的方法可以让它发挥作用?我已经尝试过 SharedArrays 和 DistributedArrays,但还没有弄清楚如何做我想做的事。
谢谢你。
最佳答案
使用 SharedArrays 应该是相当简单的:这段代码是我脑子里想出来的,没有经过测试,但类似于
mat = SharedArray(Float64, n, n)
combs = collect(combinations([1:n],2))
chunkbreaks = linspace(0, length(combs), nworkers()+1)
@sync begin
for (i,wpid) in enumerate(workers())
@async begin
remotecall_wait(wpid, myfunc, mat, combs[chunkbreaks[i]+1:chunkbreaks[i+1]])
end
end
end
哪里
myfunc
对 mat
的指定索引执行计算.但是,我应该补充一点,除非您的相异性计算很慢,否则序列化
combs
可能会使这比单线程版本慢。您可以通过提出一种更快的策略来对分配给每个进程的索引进行编码(它可以仅通过 UnitRange{Int}
进行编码并使用 divrem
来计算出 i,j
索引)来解决这个问题。
关于parallel-processing - Julia:相异矩阵计算的高效并行化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24874226/