double型 v.s. float型

浮動小数点演算を行う際に

  • 浮動小数点型(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割程度
  • 浮動小数点演算を行う処理は,全体で数%

とも言える.つまり,サンプルで使ったプログラム中の浮動小数点関連の処理は高々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 は行っていなかったため.

いずれにせよ,iccと同じようにgccでも,

  • 精度を落とすと処理速度が向上する
  • 型を落とすと処理速度が向上する

ことはたしかな様だ.

まとめると・・・

  • 浮動小数点演算を行う際に変数の型や精度を落とすと,処理速度は向上する.
  • ただし(少なくとも手元のコードでは)1割程度しか処理時間は短くならない.

アセンブラレベルで解析すればもう少し詳細は判るのだろうけど,今日はここまで.