[演習5-2] ATLAS による Scilab の高速化

G97p 谷口 明広

1  ATLAS とは

Scilab の高速化をするにあたって, ATLAS(Automatically Tuned Linear Algebra Software) の利用を試みる.これも Scilab 同様フリーのソフトウェアであるので http://www.cs.utk.edu/~rwhaley/ATLAS から容易にソースをダウンロードすることが可能である. BLAS や LAPACK は数値計算のスピードを向上させるための便利なライブラリであるが, すべてのマシンに対して最も最適な状態であるとは限らない. ATLAS を利用することによって, 各々のマシンに最適化された BLAS や LAPACK などを作成することができる. これを利用することによって Scilab の高速化を実現する.

2  ATLASのインストール

以上のことをふまえて, まず, ATLAS をインストール・実行し, 最適化されたライブラリを作成する. 実際には次のように命令する.

$ tar zxf atlas3.16D.tgz
$ cd ATLAS
$ make
$ make install arch=Linux_P5MMX

これにより, 各々のパソコンに最適化された LAPACK や BLAS などのライブラリが

/ATLAS/lib/Linux_P5MMX/

に作成される. 作成されたライブラリは

liblapack.a
libcblas.a
libf77blas.a
libatlas.a
        libtstatlas.a

である.

3  ATLAS の Scilab への組込み

3.1  ar コマンドによる組込み

はじめに ar コマンドによる Scilab への組み込みを考える.
cd ~/ATLAS/lib/Linux_PIII/
mkdir tmp
cd tmp
ar x ~/ATLAS/lib/Linux_PIII/liblapack.a
ar x ~/ATLAS/lib/Linux_PIII/libatlas.a
ar x ~/ATLAS/lib/Linux_PIII/libf77blas.a
ar x ~/ATLAS/lib/Linux_PIII/libcblas.a
        ar x ~/ATLAS/lib/Linux_PIII/libtstatlas.a
ar r ~/scilab-2.5/libs/*.a *.o
cd ..
rm -r tmp/

とする.

ar コマンドは x を添えることにより, アーカイブファイルからオブジェクトファ イルを取り出すことができる. また r を添えることにより, アーカイブファ イルにまとめられたオブジェクトファイルを新しいオブジェクトファイルと取り換えることができる.

この後 Scilab を再構築する.

make all
make install

3.1.1  確認内容

高速化を確認するために次項のような計算を実行し ATLAS を適用した場合としない場合についてそれぞれの結果を比較した. なお実行環境は

CPU:Intel Celeron 500MHz
MEM:192MB
        OS:Vine Linux2.1

であり Scilab, ATLAS のバージョンはそれぞれ

Scilab-2.5
atlas3.16

である.

1.行列の乗算
  -->a=rand(1000,1000);b=rand(1000,1000);
  -->timer();x=a*b;timer()
2.LU 分解
  -->a=rand(1000,1000);
  -->timer();[L,U,P]=lu(a);timer()
3.QR 分解
  -->a=rand(1000,1000);
  -->timer();[Q,R,P]=qr(a);timer()
4.連立一次方程式
  -->a=rand(1000,1000);b=rand1000,1);
  -->timer();x=a\b;timer()

という計算を行ってみる.

3.1.2  検証結果

実行結果は次のとおりである.

ATLAS を適用しない場合 ATLAS を適用した場合
a*b 40.02 40.58
lu(a) 16.17 16.19
qr(a) 34.71 35.29
a\b 15.99 15.76

以上の結果を見ると Scilab は高速化されていない. そこで次の方法を試みる.

3.2  Makefile を書き換える

ATLAS によって作成されたライブラリを Makefile を書き換えることによって Scilab に組み込むことを考える.まず ATLAS によって生成されたライブラリ

liblapack.a
libcblas.a
libf77blas.a
libatlas.a
        libtstatlas.a

/Scilab-2.5/libs/

にコピーする. 次に, Makefile を読んでいくと libs の組み込みは Makefile.OBJ で行われている. その Makefile.OBJ は Makefile.OBJ.in から 作成されているので Makefile.OBJ.in を書き換えて Scilab に最適化されたライブラリを組み込む. 実際には

LIBRSCI = $(SCIDIR)/libs/liblapack.a \
          $(SCIDIR)/libs/libcblas.a \
          $(SCIDIR)/libs/libf77blas.a \
          $(SCIDIR)/libs/libatlas.a \
                  $(SCIDIR)/libs/libtstatlas.a

というコメントを Makefile.OBJ.in に付け加える.

Makefile.OBJ.in を変更した後, Scilab を再構築する.

./configure --with-tk
make all
make install

これで最適化されたライブラリを組み込んだ Scilab のインストールの完了である.

3.2.1  検証

ここで ar コマンドで組み込んだときに実行したように検証を行う. 環境, 計 算などは一緒である. 実行結果は次のとおりである.

ATLAS を適用しない場合 ATLAS を適用した場合
a*b 40.02 41.70
lu(a) 16.17 16.58
qr(a) 34.71 35.28
a\b 15.99 15.97

この結果においても Scilab の高速化が行われていないのがわかった.

そこで一度, Scilab から離れて ATLAS による高速化が比較的簡単な Octave の高速化を試してみる.

4  ATLAS による Octave の高速化

ar コマンドにより Octave に Scilab を組み込む.

cd ~/ATLAS/lib/Linux_PIII/
mkdir tmp
cd tmp
ar x ~/ATLAS/lib/Linux_PIII/liblapack.a
ar x ~/ATLAS/lib/Linux_PIII/libatlas.a
ar x ~/ATLAS/lib/Linux_PIII/libf77blas.a
ar x ~/ATLAS/lib/Linux_PIII/libcblas.a
        ar x ~/ATLAS/lib/Linux_PIII/libtstatlas.a
ar r ~/octave-2.0.16/libcruft/libcruft.a *.o
cd ..
rm -r tmp/

とする. 次に Octave を再構築する.
cd ~/octave-2.0.16/libcruft/lapack/
g77 -O2 -c ilaenv.f
cd ../../
make
make install

これによって Octave に ATLAS を組み込むことができた.結果は次のとおりで ある.

4.1  検証

実行環境, および実行計算は Scilab のときと同様である.

ATLAS を適用しない場合 ATLAS を適用した場合
a*b 52.030 5.523
lu(a) 17.431 2.602
qr(a) 66.939 27.024
a\b 16.064 16.236

という結果を得られた. 行列の乗算は 10 倍速くなり, LU 分解もかなりの高速化 が認められる. QR 分解も高速化されている. 連立一次方程式は高速化されな かった.

Scilab にもうまく組み込むことができたならば, 行列の乗算・ LU 分解などが 高速化されると思われるのでその命令の仕組みを調べて高速化することを試み る.

5  Scilab の命令の仕組み

ここでは Octave において高速化に成功している, 行列の乗算・ LU 分解の Scilab 命令系統を調べ高速化について考える.

Scilab の命令の仕組みを考える前にまず, ATLAS による高速化に成功してい る Octave の命令系統を調べる.

5.1  Octave における命令系統

Octave においては乗算の命令は,
octave-2.0.16/liboctave/dMatrix.cc

において LEVEL3 BLAS の dgemm を呼び出すことによって行列の乗算を行って いる.

また, LU 分解については

octave-2.0.16/liboctave/dbleLU.cc

において LAPACK のドライバルーチン dgesv を呼び出しており, LAPACK の dgesv を見るとその中で LAPACK の計算ルーチン dgetrf を呼び出して LU 分 解を行っている.

以上のような命令系統になっているので, Octave においては ATLAS によって 最適化された LAPACK および BLAS を利用することによって高速化を行うこと ができた.

5.2  Scilab の命令系統

同様に Scilab における命令系統を見ていく.

行列の乗算は,

scilab-2.5/routines/interf/matops.f

の subroutine の matmult で行われている. しかし, ここでは BLAS や LAPACK のルー チンは呼び出されておらず, 別の計算方法によって行われている.

また, LU 分解は

scilab-2.5/routines/interf/matlu.f

の subroutine の intlu で行われているが, ここでも BLAS や LAPACK のルーチンを 呼び出すことなく計算が行われている.

よって, ATLAS により最適化された BLAS や LAPACK をいくら組み込んでも高 速化することができない.

そこで今度は特定のコマンドについて高速化することを試みる.

5.3  行列の乗算の高速化

BLAS や LAPACK を組み込んで行くだけでは, Scilab を高速化することができ ないのがわかったので, 行列の乗算を高速化することを考える. 行列の乗算は 上で述べたように,
scilab-2.5/routines/interf/matops.f

の subroutine の matmult で行われているのだが, 読んで行くと実際には matrix * matrix の項目で dmmul を呼び出して行われている.

そこで dmmul を探していくと

scilab-2.5/routines/calelm/

に dmmul.o がある. このオブジェクトは,
dmmul.f
dmmul.f.n
dmmul.f.s

という 3 つの FORTRAN で書かれたプログラムからなっている. しかし, 実際 には dmmul.f.s が dmmul.f にコピーされているだけである. dmmul.f を読んでいくと Scilab 独自の方法で計算が行われている. そこでプログラム を書き換えることによって, BLAS のルーチンを使用し高速化することを考え る.

ここで, dmmul.f.n も見てみると, BLAS の dgemm を呼び出して行列の乗算を するプログラムが書かれている. そこで, このプログラムを dmmul.f に上書 きすれば良い.

上書きした状態で, さらに ar コマンドにて ATLAS によって最適化された BLAS や LAPACK などを組み込んだ状態にしてから再構築をする. これで行列 の乗算については最適化されたと思われる.

5.4  検証

ここで再び今までと同じ環境にて高速化が行われているか確認する.

ATLAS を適用しない場合 ATLAS を適用した場合
a*b 40.02 5.67
lu(a) 16.17 16.52
qr(a) 34.71 31.89
a\b 15.99 15.92
行列の乗算にのみついて高速化を行ったところ実際に, 8倍高速化するこ とに成功した.




File translated from TEX by TTH, version 2.80. Modified by Shin'ichi Oishi
On 31 Jan 2001, 13:44.

©Shin'ichi OISHI@Waseda University

URI: http://www.oishi.info.waseda.ac.jp/~oishi/FAQ/tani2.html