MKLの分散処理を制御して実行時間を比較してみた

過去記事の一覧はこちら。 記事一覧 - Baggage Claim


昨日はKMLの話をしたが、今日はMKL。 MKLとは、Anacondaからインストールしたpythonのnumpyで採用されている数学演算のライブラリである。 演算を勝手に複数のコアに分散してくれるため、 面倒なスクリプトを書かなくてもそこそこな実行時間が確保されるというずぼらにはありがたい仕様になっている。

mkl-service パッケージを使うと、 演算が実行されるコアの数を制御して遊ぶことができる。

mkl-service — Anaconda documentation

conda install -c anaconda mkl-service

使うのは mkl.set_num_threads()。 引数で演算を行わせるコアの数を指定する (ただしドキュメントを読むと 実際に入力値で処理されるかは保証されないと書いてある。 ちゃちな計算では無理やり分散させないというようなことを言ってるのだろうか。。。)。 これを使って、jupyter-labで簡単な演算を通してコア数を変えた場合の実行時間を比較してみよう。 筆者のマシンは8コア16スレッドのIntel i9 9990K、RAMは64GBである。

まず素直に何も指定しなかった場合。 mkl.get_max_threads()を使って分散対象となるコア数もチェックしておく (ドキュメントを見る限り、実際に分散されたコア数のログはこのパッケージでは見れないようだ)。

import numpy as np
import mkl

A = np.random.randn(10_000, 10_000)
B = np.random.randn(10_000, 10_000)

mkl.get_max_threads()

%%time
C = np.dot(A, B)

# 8
# Wall time: 5.28 s

どうやらデフォルトではしっかり8コアに分散させてくれているようだ。 次に、まったく分散させない場合の実行時間を見てみる。

mkl.set_num_threads(1)
mkl.get_max_threads()

%%time
C = np.dot(A, B)

# 1
# Wall time: 28.2 s

コア数に半比例する感じでだいぶ遅くなった。

おためしでアホな値を指定してみると、 どうやら勝手にmaxの値に調整してくれるようだ。 ただ、下手に調整しない方が計算は早い。

mkl.set_num_threads(256)
mkl.get_max_threads()

%%time
C = np.dot(A, B)

# 8
# Wall time: 5.71 s

参考にしたのはこちら。

analyticalbiotechnology.blogspot.com

qiita.com