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

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

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

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

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

変数の宣言を変更すると、その変数を使用するのに呼び出すライブラリーも変えなければならないことがあります (例: cos() の代わりに cosd() など)。また、パフォーマンスを上げる別の方法として、-fp-model [double|extended] オプションを使用して中間値の精度を上げる方法があります。しかし、この方法はすべてのデノーマル例外を排除するとは限りません。使用するアプリケーションのパフォーマンスを試してみてください。

変数の型宣言を変更すると、それが汎用型でない限り、関連するライブラリー呼び出しも変えなければならないことがあります (例: cos() の代わりに cosd() など)。また、パフォーマンスを上げる別の方法として、-fp-model [double|extended] オプションを使用して中間値の精度を上げる方法があります。しかし、この方法はすべてのデノーマル例外を排除するとは限りません。使用するアプリケーションのパフォーマンスを試してみてください。 デノーマル数を排除することにより得られるパフォーマンス・ゲインが、大きな動的範囲を持つ高い精度のデータ型の使用で発生するオーバーヘッドよりも大きいことを確認する必要があります。

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

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

これらのアーキテクチャーは、インテル® ストリーミング SIMD 拡張命令 (インテル® SSE) の FTZ (flush-to-zero) および DAZ (denormals-are-zero) 機能を利用できます。

インテル® 64 および IA-32 ベースのシステムでは、コンパイラーは -O0 以上の最適化レベルにおいて、FTZ および DAZ を有効にするコードをデフォルトでメインルーチンに挿入します。-O0 で FTZ および DAZ を有効にするには、main()PROGRAM を含むソースファイルを、–ftz または /Qftz オプションを使用してコンパイルします。-ftz または /Qftz オプションが、–mia32 あるいは /arch:IA32 オプションとともに IA-32 ベースのシステムで使用されると、コンパイラーは、ランタイム・プロセッサー・チェックに基づいて条件付きで FTZ/DAZ をセットするコードを挿入します。

Note icon

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

IA-64 アーキテクチャー

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

Note icon

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

 

関連情報