10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MKL版のnumpyを使ってみたら爆速だった(Core i9 9900K, Core i9 10980XE, Ryzen 9 3900X)

Last updated at Posted at 2021-10-06

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 を特に指定せず測定した場合

計算時間(低いほうが良い)
chart.png

Xeon E5-1650v4を基準とした相対性能(高いほうが良い)
chart (1).png

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のみ)

計算時間(低いほうが良い)
chart (2).png

Ryzen 9 3900Xを基準とした相対性能(高いほうが良い)
chart (3).png

今度は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とすると若干性能が向上する

以上、参考になれば幸いです。

参考

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?