你如何在Julia中进行并行矩阵乘法?

时间:2015-11-26 20:25:34

标签: julia

有没有一种方法在julia中进行并行矩阵乘法?我尝试使用DArrays,但它比单线程乘法慢得多。

3 个答案:

答案 0 :(得分:6)

在什么意义上并行?如果你的意思是单机,多线程,那么Julia默认这样做是因为OpenBLAS(使用的基础线性代数库)是多线程的。

如果您的意思是多机,分布式计算风格,那么您将遇到大量的通信开销,这对于非常大问题只会是值得的,并且定制方法可能是需要的。

答案 1 :(得分:5)

问题很可能是直接(可能是单线程)矩阵乘法通常使用优化的库函数执行。在OpenBLAS的情况下,这已经是多线程的。对于大小为2000x2000的数组,简单矩阵乘法

@time c = sa * sb;

导致0.3秒多线程和0.7秒单线程。

在乘法中拆分单个维度的时间会变得更糟,在单线程模式下达到17秒左右。

@time for j = 1:n
    sc[:,j] = sa[:,:] * sb[:,j]
end

共享数组

您的问题的解决方案可能是使用共享阵列,它在一台计算机上跨您的进程共享相同的数据。请注意,共享阵列仍标记为实验性数据。

# create shared arrays and initialize them with random numbers
sa = SharedArray(Float64,(n,n),init = s -> s[localindexes(s)] = rand(length(localindexes(s))))
sb = SharedArray(Float64,(n,n),init = s -> s[localindexes(s)] = rand(length(localindexes(s))))
sc = SharedArray(Float64,(n,n));

然后你必须创建一个函数,它在矩阵的子集上执行廉价的矩阵乘法。

@everywhere function mymatmul!(n,w,sa,sb,sc)
    # works only for 4 workers and n divisible by 4
    range = 1+(w-2) * div(n,4) : (w-1) * div(n,4)
    sc[:,range] = sa[:,:] * sb[:,range]
end

最后,主要过程告诉工人们自己的工作。

@time @sync begin
    for w in workers()
        @async remotecall_wait(w, mymatmul!, n, w, sa, sb, sc)
    end
end

占用0.3 seconds,这与多线程单进程时间相同。

答案 2 :(得分:4)

听起来你对密集矩阵很感兴趣,在这种情况下,请看其他答案。如果您对稀疏矩阵感兴趣,请参阅https://github.com/madeleineudell/ParallelSparseMatMul.jl