web-dev-qa-db-ja.com

非正規化フロートはC#でどのように処理されますか?

これを読んでください 魅力的な記事 非正規化フロート(0に非常に近い浮動小数点数)を使用するIntel CPUで得られる20x-200xのスローダウンについて。

SSEでこれらを0に丸めるオプションがあり、そのような浮動小数点値が検出されたときにパフォーマンスを復元します。

C#アプリはこれをどのように処理しますか?有効/無効にするオプションはありますか_MM_FLUSH_ZERO

54
Robinicks

そのようなオプションはありません。

C#アプリのFPU制御Wordは、起動時にCLRによって初期化されます。それを変更することは、フレームワークによって提供されるオプションではありません。 _ control87_2() をピンボークして変更しようとしても、長く続くことはありません。例外が発生すると、CLR内の例外処理の実装によって制御ワードが再びリセットされます。 FPUコントロールワードの別の側面に対処するために作成されたもので、浮動小数点例外のマスクを解除できます。また、グローバルな状態がそのように変更されることを期待しない他のマネージコードにも有害です。

ハードウェアを直接制御しないことは、仮想マシンでコードを実行するときの暗黙の制限です。これはネイティブコードでも簡単に実行できるわけではありません。ライブラリも、FPUがデフォルトの初期化を持つことを期待している場合に、正しく動作しない傾向があります。特に例外マスキングフラグの問題、Borlandツールで作成されたDLLには例外を有効にするコツがあり、そのような例外を処理するように記述されていない他のコードが失敗します。解決するのが非常に醜い問題であるFPUコントロールワードは、想像できる最悪のグローバル変数です。

これは、浮動小数点計算がこのように混乱しないようにするための負担になります。デノーマルを使用して計算すると、根本的に小さい値からではなくても、少なくとも有効数字の迅速な損失から、ほとんど常にナンセンスな結果が得られます。 2.2E-308未満の値を0に切り捨てるのは自由です。はい、あまり実用的ではありません。おそらく、プログラムがナンセンスな結果を通常よりも少し遅くすることは問題ありません:)

47
Hans Passant