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

Oma*_*yeh 6 julia

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

Iai*_*ing 6

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

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


Ste*_*fan 5

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

@time c = sa * sb;
Run Code Online (Sandbox Code Playgroud)

结果是0.3秒多线程和0.7秒单线程.

在乘法中分割单个维度的时间变得更糟,在单线程模式下达到大约17秒.

@time for j = 1:n
    sc[:,j] = sa[:,:] * sb[:,j]
end
Run Code Online (Sandbox Code Playgroud)

共享数组

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

# 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));
Run Code Online (Sandbox Code Playgroud)

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

@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
Run Code Online (Sandbox Code Playgroud)

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

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

0.3 seconds与多线程单进程时间同时进行.


tho*_*oly 5

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