Matrix2

行列計算の高速化

課題1:時間計測

前回の連立一次方程式解のプログラムの実行時間計測をおこなえ.時間計測はRuby側ではなく,下記を参照してCプログラムに組み込め.今は,計算時間が問題なので,実行に時間のかかるプリントアウトはコメントアウトして外せ.

#include <stdio.h>
#include <time.h>
int main(void){
// clock関数を利用
clock_t start, end;
start = clock();
printf("Hello\n");
end = clock();
printf("%5.2f\n", (double)(end-start)/CLOCKS_PER_SEC);
return 0;
}

課題2:O3オプション

コンパイルの時にO3オプションを加えよ.これは

gcc -O3 hogehoge.c

でできる.計算時間を計ると,どうなった.

課題3:rubyコントロール

2000程度まで,次元数を変えて時間を計測するRubyスクリプトを用意し,Normal版とO3版とでgnuplotで次元数と計算時間をプロットせよ.

課題4:LAPACK

dgesvの入力に関するまとめを読み,連立一次方程式のプログラムのライブラリーを入れ替えよ.LU分解についての解説も参考にせよ.コンパイルして実行時間を確かめよ.

注:変数のデフォルト

long nrhs=1, lda,ldb, info;
long *ipiv;
lda=ldb=n;
dgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info);

注:行列の配列の変更

LAPACKはFORTRANから移植されたため,通常のC言語での行列の行と列の順序[i,j]が逆である.したがって,前に作った連立方程式の解を求めるルーチンの解と一致させるには,[i,j]を入れ替える必要がある.どっちみちランダムに生成した行列に意味があるわけではないので,プログラム自身は入れ替えがなくても動く.

注:コンパイル

gcc hogehoge.c -llapack -lblas -lg2c

でコンパイル.

課題5:GFLOPS

浮動小数点演算が1秒間に何回行われたかを示す.CPU性能の基本値をFLOPSという.DGESVで1000x1000の演算をおこなうとtime x MFlops = 668.5 という定数になる.このマシンの値がどの程度か求めよ.

注:intelコンパイラ

普通はgccで十分ですが,intelなどが提供しているcompilerはよりtune upされ,高速です.freeのgcc+lapack+blasとintelのicc+mklとを比べておきます.

okubo1 bob/MatrixInverse> gcc lapack.c -llapack -lblas -lg2c -o lapack1
okubo1 bob/MatrixInverse> ./lapack1 
1000
 1000 [dim]     1.4200 [sec] #LAPACK
okubo1 bob/MatrixInverse> /usr/opt/intel/cc/9.1.042/bin/icc lapack.c \
-L/usr/opt/intel/mkl/8.1.1/lib/32 -lmkl_lapack -lmkl_ia32 -lguide -o lapack2
okubo1 bob/MatrixInverse> ./lapack2
1000
 1000 [dim]     0.1400 [sec] #LAPACK

約10倍の差.マシンの最高性能を引き出すにはソフト(コンパイラやアルゴリズム)も重要ということを肝に銘じてください.

課題6:両対数プロット

gnuplotで次元数と計算時間を両対数プロットせよ.lapack版およびnormal版で10000次元まで計算したときの計算時間を外挿せよ.

Last modified:2007/11/16 06:11:40
Keyword(s):
References:[LinuxEx]