私は C++ でリアルタイム数値ソフトウェアを作成しており、現在 Visual-C++ 2008 でコンパイルしています。現在、「高速」浮動小数点モデル ( /fp:fast
)、さまざまな最適化を使用しています。
a/b -> a*(1/b) Division by multiplicative inverse
私の計算の多くには数値的に不安定すぎます。
(参照: Microsoft Visual C++ 浮動小数点の最適化)
に切り替えると/fp:precise
、アプリケーションの実行速度が 2 倍以上遅くなります。オプティマイザーを微調整する (つまり、この特定の最適化を無効にする) か、何らかの方法で手動でバイパスすることは可能ですか?
- 実際の最小限のコード例: -
void test(float a, float b, float c,
float &ret0, float &ret1) {
ret0 = b/a;
ret1 = c/a;
}
[私の実際のコードは、ほとんどが行列関連のアルゴリズムです]
出力: VC (cl、バージョン 15、0x86) は次のとおりです。
divss xmm0,xmm1
mulss xmm2,xmm0
mulss xmm1,xmm0
2 つではなく 1 つの div を持つことは、数値的には大きな問題です (xmm0 は RAM から 1.0f でプリロードされます)。 SSE なしでコンパイルすると、同様の stack-x87-FPU コードが出力されます)。
関数をラップする
#pragma float_control( precise, on, push )
...
#pragma float_control(pop)
精度の問題は解決しますが、第一に、関数レベル (グローバル スコープ) でのみ利用可能であり、第二に、関数のインライン化を防ぎます (つまり、速度のペナルティが高すぎます)。
「正確な」出力も「ダブル」にキャストされています。
divsd xmm1,xmm2
cvtsd2ss xmm1,xmm1
divsd xmm1,xmm0
cvtpd2ps xmm0,xmm1