Il risolutore di sistemi lineari è anche multithread in Julia come in Matlab? E come "multithread" in Julia?

Sep 28 2020

Sto cercando di confrontare velocità e prestazioni tra Matlab e Julia. Sto guardando un codice che ottimizza la topologia di una struttura continua soggetta a un determinato carico. Il codice che sto guardando è il codice pubblico topopt88.m:https://www.topopt.mek.dtu.dk/Apps-and-software/Efficient-topology-optimization-in-MATLAB

Essenzialmente è un algoritmo iterativo dove in ogni iterazione viene risolto un sistema Ax = b (x = A \ b), dove A dipende dal progetto strutturale (è la matrice di rigidezza agli elementi finiti) e viene aggiornato ad ogni iterazione.

In Julia lo stesso codice è più lento di Matlab. Ho ottimizzato il codice in Julia, dichiarando i tipi nelle definizioni delle funzioni, utilizzando le funzioni il più possibile, evitando le variabili globali e implementando altri suggerimenti che ho trovato su Internet. Ma Julia è ancora più lenta dello stesso codice Matlab (lo stesso nel senso dei passaggi concettuali).

La mia domanda: poiché il sistema Matlab risolve "\" è multi thread per impostazione predefinita , è vero lo stesso per Julia? In caso contrario, come eseguire il multi thread dell'operatore \ di Julia o ottenere accelerazioni dalla parallelizzazione in modo simile?

Risposte

2 PrzemyslawSzufel Sep 28 2020 at 06:35

Per impostazione predefinita, Julia utilizza BLAS / OpenBLAS e puoi configurarlo in modo che sia multi-thread. Ciò richiede l'esecuzione di Julia in un'impostazione multi-thread e l' impostazione della BLAS.set_num_threads()configurazione.

Ecco come:

Prima di iniziare Julia:

set JULIA_NUM_THREADS=4

o su Linux

export JULIA_NUM_THREADS=4

Ora testiamo in un singolo thread:

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)

Ora il multi-thread:

julia> using LinearAlgebra

julia> BLAS.set_num_threads(4)

julia> @btime A \ b;
  175.701 μs (4 allocations: 20.61 KiB)

Puoi vedere che sulla mia macchina la velocità è più di 2x.

Un'altra opzione per aumentare la velocità sarebbe quella di passare Julia a MKL.

julia> pkg"add https://github.com/JuliaComputing/MKL.jl"
julia> pkg "build MKL"
# restart Julia

Non l'ho usato MKL.jlquindi se ci provi, scrivi come è stato confrontato.

shuli Sep 28 2020 at 19:44

Quella che segue è la migliore soluzione attuale che ho trovato e che mi dà le migliori prestazioni. Fuori da Julia in un terminale di tipo Windows set JULIA_NUM_THREADS=4. Avvia Julia e usa il modulo Algebra lineare in questo modo:using LinearAlgebra BLAS.set_num_threads(1)

In questo modo ci saranno 4 thread, e impostando i thread BLAS su 1 fondamentalmente non utilizzerà il proprio pool che sembra essere in conflitto con il pool di thread Julia, o almeno per rallentare le prestazioni per me. Ho qualche suggerimento al riguardo qui:https://discourse.julialang.org/t/julia-threads-vs-blas-threads/8914/15 La mia attuale impostazione BLAS in Julia 1.5.1 è julia> BLAS.vendor() :openblas64

L'utilizzo di Pardiso.jl con il solutore sparse MKL predefinito non ha aiutato. Ho ancora bisogno di capire se c'è un modo per aumentare le prestazioni anche lì e come.