问题描述
我正在尝试比较Matlab和Julia的速度和性能。我正在看一个代码,该代码对给定负载下的连续体结构进行拓扑优化。我正在查看的代码是公共代码topopt88.m:https://www.topopt.mek.dtu.dk/Apps-and-software/Efficient-topology-optimization-in-MATLAB
从本质上讲,它是一种迭代算法,其中,每次迭代都求解Ax = b系统(x = A \ b),其中A取决于结构设计(它是有限元刚度矩阵),并且每次更新迭代。
在Julia中,同一代码的运行速度比Matlab慢。我在Julia中做了一些代码优化,在函数定义中声明类型,尽可能使用函数,避免使用全局变量,并实现我在Internet上找到的其他技巧。但是Julia仍然比相同的Matlab代码(在概念步骤上相同)要慢。
我的问题:由于Matlab系统求解“ \”为multi threaded by default,对于Julia来说是否一样?如果不是,该如何对Julia的\运算符进行多线程处理,或者类似地从并行化中提高速度?
解决方法
默认情况下,Julia使用的是BLAS / OpenBLAS,您可以将其配置为多线程。这需要在多线程设置和设置BLAS.set_num_threads()
中运行Julia。
方法如下:
开始朱莉娅之前:
set JULIA_NUM_THREADS=4
或在Linux
上export JULIA_NUM_THREADS=4
现在让我们在一个线程中进行测试:
julia> using BenchmarkTools,Random
julia> const b = rand(50);
julia> const A = rand(50,50);
julia> @btime A \ b;
424.899 μs (4 allocations: 20.61 KiB)
现在是多线程了:
julia> using LinearAlgebra
julia> BLAS.set_num_threads(4)
julia> @btime A \ b;
175.701 μs (4 allocations: 20.61 KiB)
您可以看到在我的机器上,速度提高了2倍以上。
另一个加快速度的选择是将Julia切换为MKL。
julia> pkg"add https://github.com/JuliaComputing/MKL.jl"
julia> pkg "build MKL"
# restart Julia
我还没有使用MKL.jl
,因此,如果您尝试一下,请写出它的基准测试方法。
以下是我找到的当前最佳解决方案,它为我提供了最佳性能。
在Windows终端中的Julia外部,键入set JULIA_NUM_THREADS=4
。启动Julia并以这种方式使用线性代数模块:
using LinearAlgebra
BLAS.set_num_threads(1)
通过这种方式,将有4个线程,并且通过将BLAS线程设置为1,它基本上将不会使用自己的似乎与Julia线程池冲突的池,或者至少会降低我的性能。
在这方面,我得到了一些提示:https://discourse.julialang.org/t/julia-threads-vs-blas-threads/8914/15
我当前在Julia 1.5.1中的BLAS设置是
julia> BLAS.vendor()
:openblas64
将Pardiso.jl与默认的MKL稀疏求解器结合使用无济于事。我仍然需要弄清楚是否还有一种方法可以提高性能,以及如何提高性能。