浮動小数点演算を行う際に
- 浮動小数点型(floatかdoubleかlong doubleか)
- 計算精度
を変えると,実際にどれくらい計算速度が異なるのか測定してみた.
測定した環境は fedora core 5 ベースのlinuxで,中身としては
という普通のLinuxマシン.
計算速度を測定する際に用いたソースコードは手元の数値計算を行うプログラムで,計算結果の正しさについては今回は無視した.
intelコンパイラの場合
まずは,intelコンパイラで,浮動小数点型と,計算精度の全ての組み合わせについて,計算時間を測定してみた.
intelコンパイラのバージョンは,icc 9.1 20060816.intelコンパイラは, -pc{80|64|32} オプションで計算精度を指定できる.つまり,-pc80 なら 80bit精度, -pc32なら32bit精度となる.コンパイルオプションで "-O3 -xN -pc??" を指定した場合の,測定結果は以下の通り.
型 | -pc80 | -pc64 | -pc32 |
---|---|---|---|
long double | 2.456s | 2.416s | 2.376s |
double | 2.232s | 2.220s | 2.188s |
float | 2.188s | 2.160s | 2.156s |
だいたい予想通の結果である.
つまり,
- long double > double > float と計算時間が短くなる.(おそらくメモリの消費量が減るため)
- 80bit > 64bit > 32bit と計算時間が短くなる.(おそらくCPUの計算量が減るため)
という傾向が観測できた.すなわち
- long double > double > float と型を切り替えると,速度は1割程度づつ向上し,
- 計算精度を落とすと 数%処理速度が向上する
傾向が見受けられた.
もちろん,この結果はアルゴリズムに大きく依存する.上記の結果は言い方を変えれば,
とも言える.つまり,サンプルで使ったプログラム中の浮動小数点関連の処理は高々1割しか無かった訳だ.
いずれにせよ,少なくとも自分が書くようなプログラムでは,double 型をfloat 型に切り替えたところで劇的に計算時間が短くなることは無いらしい.
gcc の場合
上記と同様の実験を gcc-4.1.1 (20060619) でも行った.計算精度の指定は 先日の日記*1で書いた FLT_EVAL_METHOD で指定した.
コンパイルオプションで "-O3 -DFLT_EVAL_METHOD=?" を指定した場合の,測定結果は以下の通り.
型 | FLT_EVAL_METHOD=2 | FLT_EVAL_METHOD=1 | FLT_EVAL_METHOD=0 |
---|---|---|---|
long double | 3.82s | 3.508s | 3.520s |
double | 3.548s | 3.504s | 3.460s |
float | 3.404 | 3.340s | 3.396s |
まず icc に比べてgccが生成するバイナリは遅い.これはiccがベクトル化を行っていたのに対して,gcc は行っていなかったため.
- 精度を落とすと処理速度が向上する
- 型を落とすと処理速度が向上する
ことはたしかな様だ.