x87 FPU で厳密な単精度演算を行うコスト (2)
そうそう書き忘れてましたが, add や sub に比べて一部の multi や div が数十倍速くなっているのは,実際にはコンパイル時に浮動小数点数のループ計算が行われていて,その結果が直接埋め込まれるからです.実行時に計算しているわけじゃないので速度比較では注意しないといけませんね.
/fp:strictの結果
type add(ms) sub(ms) multi(ms) div(ms) 計算結果 double 962.3 962.8 21.7 20.4 0 flaot 947.1 943.7 998.4 4210.8 -1.67772e+007 double(template) 938.8 947.1 20.1 17.4 0 float (template) 945.2 945.5 996.9 4251.5 -1.67772e+007 double(template specialization) 1021.9 1021.7 25.1 23.5 0 float(template specialization) 1078.4 1063.7 1132.9 4979.7 -1.67772e+007 floatの乗算・除算が目も当てられない状態になってしまいました。
多分実際に実行時に計算を行うとその,「目も当てられない状態」は結構真実に近いんじゃないかと.
詳しくはこのあたりを参照のこと.
- /fp (浮動小数点の動作の指定)
- Microsoft Visual C++ Floating-Point Optimization
- Method for getting /Op like consistency in MS C++ 14.0
コンパイル時計算の回避方法については,ちょっと知識に怪しいところがあったのでまた後ほど.
(追記)
fenv_access を ON にして /fp:precise を使用すると、浮動小数点式のコンパイル時間の評価などの一部の最適化が無効になります。
Using /fp:precise with fenv_access ON disables some optimizations such as compile-time evaluations of floating point expressions.
浮動小数点プラグマの使い方が無効です: fenv_access プラグマは precise モードでのみ操作します
とあるので,precise モードで fenv_access ON とすると,コンパイル時評価“も”無効になるようですね.