8

私は 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 
4

5 に答える 5

3

追加します

#pragma float_control( precise, on)

計算前と

#pragma float_control( precise,off)

その後。私はそれがそれをするべきだと思います。

于 2010-08-04T16:39:09.963 に答える
2

そのドキュメントには、プラグマを使用して行ごとに浮動小数点の最適化を制御できると記載されています。

于 2010-08-04T16:16:38.863 に答える
1

__assume もあります。__assume(a/b != (a*(1/b))) を使用できます。実際に __assume を使用したことはありませんが、理論上はオプティマイザーを微調整するために存在します。

于 2010-08-08T15:15:19.803 に答える
0

これらの計算を含む関数を別のソース コード ファイルに配置し、そのファイルのみを異なる設定でコンパイルできますか?

それが安全かどうかはわかりませんが、確認する必要があります。

于 2010-08-04T16:17:37.527 に答える
0

私が見つけた(奇妙な)解決策:関数で同じ値で割るたびに、いくつかのイプシロンを追加します:

    a/b; c/b 

->

    a/(b+esp1); c/(b+esp2)

また、ゼロによる時折のdivからあなたを救います

于 2010-08-08T15:03:48.417 に答える