デノーマル数は、IEEE* 浮動小数点表現で、仮数がゼロ以外、指数がゼロの数です。ゼロよりも大きな最も小さな単精度の正規浮動小数点数は、約 1.175494350822288e-38 です。より小さな数も可能ですが、それらはデノーマル数で、ハードウェアやオペレーティング・システムで処理するには数百クロックサイクル必要です。
アルゴリズムの選択を誤ると、デノーマルな範囲で多くの演算が行われます。そのため、たいていの場合、デノーマル数があるということは、アルゴリズムに問題があることを示します。デノーマル数を制御する方法はいくつかあります。例えば、正規数に変換して (大きなスカラー数を掛けて)、正規空間で残りの演算を行った後で、デノーマル範囲に戻す方法があります。小さなデノーマル値がプログラム設計に必要な場合は常にこの方法を行ってください。多くの場合、ゼロとしてみなすことのできるデノーマル数はゼロにフラッシュされます。
デノーマル数は、Itanium(R) プロセッサーではソフトウェアで計算されます。計算には数百クロックサイクル必要で、多くのカーネル時間が費やされます。なぜデノーマル結果が発生するのかを理解し、それらが許容されるかどうかを判断するようにしてください。許容されないと判断した場合、次に提案する方法を使用して、結果を制御してください。
値を正規値に変換します。
より長いデータ型を使用して、精度を上げて範囲を広くします。
浮動小数点制御レジスターで FTZ モードを設定します: -ftz (Linux*) または /Qftz (Windows*)。
デノーマル数は、常に、精度の損失、アンダーフロー、およびエラー (または少なくとも必要条件に満たないこと) を示します。インテル(R) Pentium(R) 4 プロセッサーおよびインテル Itanium プロセッサーでは、デノーマル値を生成する浮動小数点演算をゼロにセットできるので、パフォーマンスが向上します。
インテル(R) コンパイラーは、-fp-model (Linux) または /fp (Windows) オプションでサポートされている、strict、precise、source、double、および extended モデルを含む value-safe オプションが指定されると、FTZ および DAT ビットを無効にします。
IA-32 コンパイラーは -ftz (Linux) または /Qftz (Windows) オプションをサポートしませんが、-xK または -xW (Linux)、/QxK または /QxW (Windows) は適切なアプローチで SSE 制御レジスタに FTZ モードを設定します。インテル Pentium 4 プロセッサーで FTZ (Flush-to-Zero) モードを有効にする唯一の方法は、次の例に示すように、SSE2 制御レジスターを手動でプログラムする方法です。
例 |
---|
void SIMDFlushToZero (void) { DWORD SIMDCtrl; _asm { STMXCSR SIMDCtrl mov eax, SIMDCtrl // flush-to-zero = bit 15 // mask underflow = bit 11 // denormals are zero = bit 6 or eax, 08840h mov SIMDCtrl, eax LDMXCSR SIMDCtrl } } |
Mac OS*: -ftz オプションはサポートされていません。
FTZ (Flush-to-Zero) または特定のビット・フィールド設定についての詳細は、『IA-32 インテル(R) アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル上巻: 基本アーキテクチャ』 (http://www.intel.com/jp/developer/download/) を参照してください。
Itanium コンパイラーは、アプリケーションが漸次アンダーフロー・モードの場合に、デノーマル結果をゼロにフラッシュする -ftz (Linux)、/Qftz (Windows) オプションをサポートしています。このオプションは、デノーマル値がアプリケーション動作に影響を与えない場合に使用します。オプションのデフォルトの状態はオフです。デフォルトでは、コンパイラーは結果を漸次アンダーフローにします。
main() で開始されたプロセスの FTZ (Flush-to-Zero) モードをオンにするには、main() を含むソースで -ftz (Linux) または /Qftz (Windows) オプションを使用してください。初期スレッドおよびそのプロセスによってその後に作成されるあらゆるスレッドは、FTZ モードで動作します。
デフォルトでは、-O3 (Linux) または /O3 (Windows) オプションは FTZ モードを有効にします。対照的に、-O2 (Linux) または /O2 (Windows) オプションは FTZ モードを無効にします。代わりに、-no-ftz (Linux) または /Qftz- (Windows) を使用して、デノーマル結果をゼロにフラッシュしないようにすることもできます。
マイクロアーキテクチャー上の最適化およびサイクル計算に関する詳細な最適化情報は、『インテル(R) Itanium(R) 2 プロセッサ マイクロアーキテクチャ最適化入門: リファレンス・マニュアル』 (http://www.intel.com/jp/developer/download/) を参照してください。
いくつかの浮動小数点アプリケーションは、終了しないことで、非常にパフォーマンスが悪くなります。多くの場合、指定された値に対して正確な浮動小数点比較が行われるため、アプリケーションは終了しません。次の例で、この概念について説明します。
例 |
---|
if (foo() == 2.0) |
ここで、foo() は正確に 2.0 に一致することなく、2.0 に可能な限り近づきます。次に示すように、不正確な浮動小数点比較またはファジー比較を使用して、値が特定の許容誤差内にあることをテストすることで、コードのパフォーマンスを向上できます。
例 |
---|
epsilon = 1E-8; if (abs(foo() - 2.0) <= epsilon) |