デノーマル例外の影響の軽減

正規化されていない浮動小数点値は、正規化で表現するには小さすぎる値です。例えば、仮数は左揃えにできません。デノーマル値を処理するには、ハードウェアまたはオペレーティング・システムの介入が必要です。そのため、結果がデノーマル値になる浮動小数点演算はパフォーマンスに影響することがあります。

デノーマル数を処理し、アプリケーションのパフォーマンスを高める方法はいくつかあります。

例えば、大きなスカラー数を掛けて正規数に変換し、正規空間で残りの演算を行った後で、デノーマル範囲に戻す方法があります。小さなデノーマル値がプログラム設計に必要な場合はこの方法を検討してください。

より大きな動的範囲を持つ高い精度のデータ型を使用する方法もあります。例えば、float として宣言された変数を double として宣言するように変換します。 ただし、変更を加えることは、プログラムの遅延を引き起こしたり、必要な容量が増える (データのロードと保存にさらに時間がかかる) 可能性があることに注意してください。また、SSE 命令のスループットが悪くなることもあります。

変数の宣言を変更すると、その変数を使用するのに呼び出すライブラリーも変えなければならないことがあります (例: cos() の代わりに cosd() など)。また、パフォーマンスを上げる別の方法として、-fp-model [double|extended] オプションを使用して中間値の精度を上げる方法があります。しかし、デノーマル数によるパフォーマンス低下へのソリューションとして精度を上げた場合は、その変更によって実際にパフォーマンスが向上したことを確認する必要があります。

最後に、多くの場合、デノーマル数はプログラム結果に大きな影響を与えることなく、ゼロとして安全に扱われます。対象とするアーキテクチャーによって、FTZ (Flush-to-Zero) オプションを使用してください。

IA-32 およびインテル(R) 64 アーキテクチャー

ストリーミング SIMD 拡張命令 (SSE)、ストリーミング SIMD 拡張命令 2 (SSE2)、ストリーミング SIMD 拡張命令 3 (SSE3)、ストリーミング SIMD 拡張命令 3 補足命令 (SSSE3) の FTZ および DAZ (denormals are zeros) 機能を利用できます。

デフォルトでは、IA-32 アーキテクチャーのコンパイラーは、SSE 命令をサポートしないマシンでも実行できるコードを生成します。コンパイラーは、FTZ および DAZ 設定の利点を得られない x87 浮動小数点演算ユニットを使用して浮動小数点演算を実装します。-x (Linux* および Mac OS*) または /Qx (Windows*) オプションを使用すると、SSE 命令および SSE2 命令により、浮動小数点演算を実装するように指定できます。インテル 64 対応のコンパイラーは、デフォルトで SSE2 命令を生成します。

インテル(R) コンパイラーでコンパイルする際、ソースファイルに main() が含まれていると、FTZ と DAZ モードはデフォルトで有効になります。コンパイラーは、ランタイム・プロセッサー・チェックを行うライブラリー・ルーチンへの呼び出しを生成します。FTZ および DAZ モードは、プログラムが実行されるマシンで利用できるようにセットされます。

IA-64 アーキテクチャー

-ftz (Linux および Mac OS) または /Qftz (Windows) オプションを使用して、main() が含まれるソースファイルに対し、FTZ モードを有効にします。-O3 (Linux および Mac OS) または /O3 (Windows) オプションは、自動で -ftz あるいは /Qftz を有効にします。

FTZ を使用した後、正規化されていない値をゼロとして解釈した場合でも、プログラムが正しい結果を出力していることを確認してください。

関連情報