在什么意义上平行?如果你的意思是单机,多线程,那么Julia默认这样做是因为OpenBLAS(使用的基础线性代数库)是多线程的.
如果您的意思是多机,分布式计算风格,那么您将遇到大量的通信开销,这对于非常大的问题只会是值得的,并且可能需要定制方法.
问题很可能是直接(可能是单线程)矩阵乘法通常使用优化的库函数执行.在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与多线程单进程时间同时进行.
听起来您对密集矩阵感兴趣,在这种情况下请参阅其他答案。如果您对稀疏矩阵感兴趣,请参阅https://github.com/madeleineudell/ParallelSparseMatMul.jl。