AMD Ryzenでそのままnumpyを動かすと遅くなるので、mklを利用できるnumpyをインストール必要があることを知りました。
どの程度変わるのか手元の環境で確認したら、Intel版でも爆速になったので、インストール手順と合わせてパフォーマンス比較結果をまとめたいと思います。
環境
Xeon E5-1650 v4
CPU : Xeon E5-1650 v4 6C/12T @3.6GHz
RAM : DDR4-2133 8GB x 8 (Total 64GB)
OS : Ubuntu 20.04 (Docker)
Core i9 9900K
CPU : Core i9 9900K 8C/16T @3.6GHz
RAM : DDR4-2133 16GB x 4 (Total 64GB)
OS : Ubuntu 20.04 (Docker)
Core i9 10980XE
CPU : Core i9 10980XE 18C/36T @3.0GHz
RAM : DDR4-2133 32GB x 8 (Total 256GB)
OS : Ubuntu 20.04 (Docker)
Ryzen 9 3900X
CPU : Ryzen 9 3900X 12C/24T @3.8GHz
RAM : DDR4-3600 32GB x 2 (Total 64GB)
OS : Ubuntu 20.04 (Docker)
mkl版numpy(&scipy) のインストール方法
ローカル環境
まず、Intel MKLをインストールします。
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB \
&& sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB \
&& rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB
sudo wget https://apt.repos.intel.com/setup/intelproducts.list -O /etc/apt/sources.list.d/intelproducts.list
sudo apt update && sudo apt install -y intel-mkl-2020.0-088
※インストールするバージョンは適宜変更してください。(https://software.intel.com/content/www/us/en/develop/tools/oneapi/base-toolkit/download.html?operatingsystem=linux)
pipでインストールされているnumpyとscipyをアンインストールします。
python3 -m pip uninstall -y numpy scipy
~/.numpy-site.cfg
にmkl driverを利用するよう記述します。
echo "[mkl] \n\
library_dirs = /opt/intel/mkl/lib/intel64 \n\
include_dirs = /opt/intel/mkl/include \n\
mkl_libs = mkl_rt \n\
lapack_libs =" > ~/.numpy-site.cfg
強制的にビルドするオプションを付けて、numpyとscipyをインストールします。
python3 -m pip install --no-binary :all: numpy
python3 -m pip install --no-binary :all: scipy
Docker環境
Dockerfileに下記のように記述します。
# install mkl
WORKDIR /tmp
RUN wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB \
&& apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB \
&& rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB
RUN wget https://apt.repos.intel.com/setup/intelproducts.list -O /etc/apt/sources.list.d/intelproducts.list
RUN apt update && apt install -y \
intel-mkl-2020.0-088
# install numpy of mkl version
RUN python3 -m pip uninstall -y numpy scipy
RUN echo "[mkl] \n\
library_dirs = /opt/intel/mkl/lib/intel64 \n\
include_dirs = /opt/intel/mkl/include \n\
mkl_libs = mkl_rt \n\
lapack_libs =" > ~/.numpy-site.cfg
RUN python3 -m pip install --no-binary :all: numpy
RUN python3 -m pip install --no-binary :all: scipy
パフォーマンス評価
テスト関数
下記のテスト関数でパフォーマンスを計測しました。
import numpy as np
import time
N_LOOP = 50
def testfunc(x):
np.random.seed(x)
X = np.random.randn(2000, 4000)
np.linalg.eigh(X @ X.T)
calc_time_list = []
for i in range(N_LOOP):
t_start = time.time()
testfunc(0)
t_end = time.time()
calc_time_list.append(t_end - t_start)
print("[{} / {}] calculation time : {:.4f} s".format(i, N_LOOP, t_end - t_start))
calc_time_ndarr = np.array(calc_time_list)
print("===========================================================")
np.show_config()
print("===========================================================")
print("ave : {:.4f} s, std : {:.4f} s, min : {:.4f} s, max : {:.4f} s".format(np.average(calc_time_ndarr),
np.std(calc_time_ndarr),
np.min(calc_time_ndarr),
np.max(calc_time_ndarr)))
テスト条件
環境に示した4種類について、OpenBLASとMKLでそれぞれ測定しました。MKL_DEBUG_CPU_TYPE
による効果を確認するため、Ryzen 9 3900Xのみ、MKL_DEBUG_CPU_TYPE=5
として測定も行いました。
各測定50回ずつ行い、その平均値を比較しています。
テスト結果
MKL_NUM_THREADS
を特に指定せず測定した場合
Xeon E5-1650v4を基準とした相対性能(高いほうが良い)
MKLを使用した場合、Intel・AMDに依らず、OpenBLASに比べて大幅に性能が向上することを確認できました。およそ40倍程度高速になっています。
また、AMD環境でMKLを使用している場合、MKL_DEBUG_CPU_TYPE=5
とすることで、若干の性能向上が期待できることを確認できました。
今回の検証では、MKL_DEBUG_CPU_TYPE=5
とすることで、Ryzen 9 3900XがCore i9 9900Kを逆転し、最も性能が高くなっています。
一方で、最もスレッド数の多いCore i9 10980XEの性能が思ったよりも振るわなかったのは、シングルスレッド性能の低さの影響でしょうか。
それを検証するため、今度は MKL_NUM_THREADS=1
として、純粋なシングルスレッド性能を見てみました。
MKL_NUM_THREADS=1
としてシングルスレッドで測定した場合(一部環境、MKLのみ)
Ryzen 9 3900Xを基準とした相対性能(高いほうが良い)
今度はCore i9 9900Kが最も性能良いという結果になりました。CINEBENCH R20のシングルスレッド性能で比較すると、Core i9 9900Kが518、Ryzen 9 3900Xが502、Core i9 10980XEが480なので、ほぼ予想通りの結果と言えると思います。
以上の結果から、MKL版のnumpyでMKL_DEBUG_CPU_TYPE=5
とすることにより、AMD Ryzenでも性能を出せることが確認できました。
まとめ
MKL版のnumpyがOpenBLAS版よりも想像以上に早かったため、比較記事にしてみました。個人的にわかったこととしては下記2点です。
- Intel、AMDに依らず、numpyを使うなら手動ビルドでMKL版のnumpyをインストールしたほうが良い
- AMD Ryzenの場合、
MKL_DEBUG_CPU_TYPE=5
とすると若干性能が向上する
以上、参考になれば幸いです。