見出し画像

OpenBLAS, ATLAS, BLASとの性能比較|行列積高速化#28

そこそこ高速な実装ができたので、他のBLASライブラリが持つDGEMMと性能比較を行ってみましょう。

比較を行うライブラリとしては、下記を使用しました。

1、BLAS(NetLibの参照実装)
2、ATLAS
3、OpenBLAS

これらのライブラリについては、下記でも紹介しています。

GCCの準備

評価環境として使用しているMacBookでは、OpenBLASはbrewでインストール可能でしたが、BLASとATLASは独自にコンパイルする必要がありました。

コンパイルにあたり、デフォルトのコンパイラclangだと色々な問題が発生したため、brewを使用してあらかじめインストールしておいたgcc10とgfortranをコンパイラとして使用しました。

$brew install gcc gfortran


OpenBLASのインストール

OpenBLASは下記のコマンドでインストールできました。

$ brew install openblas

OpenBLASは、/usr/local/Cellar/openblas/0.3.10_1/libにインストールされているため、MakefileのLDFLAGSにパスを追加する必要があります。

LDFLAGS=-L./lib/ -L/usr/local/Cellar/openblas/0.3.10_1/lib/
CBLASLIBS= -lcblas -lopenblas


ATLASのインストール

ATLASは、まずsourceforgeからソースコードatlas3.10.3.tar.bz2をダウンロードします。

次のコマンドで解凍後、作成されたATLASディレクトリに移動します。

$ tar jxvf atlas3.10.3.tar.bz2
$ cd ATLAS/

次に、評価環境専用のディレクトリを任意の名前で作る必要があります。ここでは、ディレクトリ名をATLAS_MacOSXとしました。その後、作成したディレクトリに移動します。

$ mkdir ATLAS_MacOSX
$ cd ATLAS_MacOSX

ATLASでは、configureでCPUを推測してくれるのですが、評価環境のMacBookの場合はエラーが出て、推測に失敗してしまいました。結局、必要なパラメータをコマンドラインオプションとして指定する必要がありました。

一つ上のディレクトリにあるconfigureスクリプトを実行したあと、makeを実行します。コマンドは、下記の通りです。

$ ../configure --prefix=./install -O OSX -A UNKNOWNx86 -V 16 -b 64 -t 2 -m 2900 
$ make

インストール先を決める--prefixには、一旦その場に作成されるように./installを指定しました。-OはOS名、-AはCPU名、-Vは使用する命令セットのビットフラグ、-bはアドレスのビット数(64bit)、-tはスレッド数、-mはMHz単位の動作周波数(2900MHz)です。

OS名やCPU名、及び命令セットは、途中で作成されるxprint_enumを実行すると確認できます。CPU名には、適切なものがなかったのでUNKNOWNx86を選びました。命令セットは、AVXMAC=16を選んでいます。

makeコマンドで、自動チューニングが始まりますが、これには時間がかかります。経験上では3~4時間かかることが多いですが、今回は62時間(約2.5日)かかりました。。。

自動チューニングが完了したら、完成したライブラリを適当なディレクトリに移動させます。今回は、OpenBLASと同じく、/usr/local/Cellarの配下に移動しました。

$ mv ./install /usr/local/Cellar/atlas

ただし、ATLASが作成したライブラリlibcblas.aは、BLASが作成するlibcblas.aと名前が重複するので、ATLASが作成したものをlibcblas_atlas.aに変更しました。

最後に、atlasをリンクする場合には、Makefileで次のように指定します。

LDFLAGS=-L./lib/ -L/usr/local/Cellar/atlas/lib/
CBLASLIBS=  -lcblas_atlas -latlas


BLASのインストール

NetLib.orgの下記のサイトから、blas-3.8.0.tgz、cblas.tgz、及びcblas.hをダウンロードします。

拡張子は.tgzですが、実施にはgzip圧縮はされていないので、次のようなtarコマンドで解凍します。

$ tar xvf blas-3.8.0.tgz
$ tar xvf cblas.tgz

解凍すると、BLAS-3.8.0/およびCBLAS/ディレクトリが作成されます。

ビルドの前に、環境に合わせて設定ファイルBLAS-3.8.0/make.incおよびCBLAS/Makefile.inを修正する必要があります。今回は、次のように設定しました。

$ cat BLAS-3.8.0/make.inc 
####################################################################
#  BLAS make include file.                                         #
#  March 2007                                                      #
####################################################################
#
SHELL = /bin/sh
#
#  The machine (platform) identifier to append to the library names
#
PLAT = _MACOSX
#  
#  Modify the FORTRAN and OPTS definitions to refer to the
#  compiler and desired compiler options for your machine.  NOOPT
#  refers to the compiler options desired when NO OPTIMIZATION is
#  selected.  Define LOADER and LOADOPTS to refer to the loader and 
#  desired load options for your machine.
#
FORTRAN  = gfortran
OPTS     = -O3 -mavx2
DRVOPTS  = $(OPTS)
NOOPT    =
LOADER   = gfortran
LOADOPTS =
#
#  The archiver and the flag(s) to use when building archive (library)
#  If you system has no ranlib, set RANLIB = echo.
#
ARCH     = ar
ARCHFLAGS= cr
RANLIB   = ranlib
#
#  The location and name of the Reference BLAS library.
#
BLASLIB      = ../../lib/libblas.a
$ cat CBLAS/Makefile.in 
#
# Makefile.LINUX
#
#
# If you compile, change the name to Makefile.in.
#
#
#-----------------------------------------------------------------------------
# Shell
#-----------------------------------------------------------------------------
SHELL = /bin/sh
#-----------------------------------------------------------------------------
# Platform
#-----------------------------------------------------------------------------
PLAT = MACOSX
#-----------------------------------------------------------------------------
# Libraries and includs
#-----------------------------------------------------------------------------
BLLIB = ../../../lib/libblas.a
CBLIB = ../../../lib/libcblas.a
#-----------------------------------------------------------------------------
# Compilers
#-----------------------------------------------------------------------------
CC = gcc
FC = gfortran
LOADER = $(FC)
#-----------------------------------------------------------------------------
# Flags for Compilers
#-----------------------------------------------------------------------------
CFLAGS = -O3 -mavx2 -DADD_
FFLAGS = -O3 -mavx2
#-----------------------------------------------------------------------------
# Archive programs and flags
#-----------------------------------------------------------------------------
ARCH = ar
ARCHFLAGS = r
RANLIB = echo

以上の設定ができたら、下記のコマンドを使ってビルドします。

$ cd BLAS-3.8.0
$ make
$ cd ../CBLAS
$ make alllib


性能比較

BLASライブラリを差し替えてDGEMMの実行性能を測定したところ、次のようになりました。

DGEMM性能比較AVX2

縦軸は、理論ピーク性能比率(=FLOPS/PEAK FLOPS)を表しています。横軸は、正方行列の片方のサイズを表しています。つまり、横軸1000の場合は1000x1000の大きさの行列積を計算しています。

myblas(青線)が、今回作成した行列積計算プログラムです。行列サイズが大きくなると、およそ90~93%の性能が出ています。しかし、openblas(オレンジ線)は、だいたい97~101%の性能が出ています(100%を超えるのは、演算数カウントが多すぎるのかもしれません)。従って、およそ7%前後のopenblasよりも劣っていることが分かります。ただし、ほぼ同じ曲線を描いているので、高速化チューニングとして同じような実装を行っていると推測されます。

atlas(黄色線)は、自動チューニングに失敗しているのでしょう。これまでの経験上では、80%から90%の性能は出るはずです。これは、指定したオプションが適切ではなかった可能性が高いです。(でも、自動チューニングに2.5日かかったので、もう一度ビルドする気になれません・・・)

blas(灰色線)は、小さい行列では20%を超える性能が出ています。-mavx2オプションなしだと10%前後の性能だったため、これはAVX命令の効果だと考えられまう。しかし、行列サイズが大きくなると、10%前後に性能が落ちて来ています。これまでの経験上でも、blasは10%程度の性能でした。


まとめ

同じような曲線を描くものの、OpenBLASの方が7%前後高速でした。

さすがですね。

高速化のポイントが、もう1つか2つほどあるのかもしれません。

次の記事

ソースコード


この記事が気に入ったらサポートをしてみませんか?