インテル® C++ コンパイラー XE 13.1 ユーザー・リファレンス・ガイド
一般に、浮動小数点アプリケーションのプログラミングの目標は、次のカテゴリーに分けられます。
精度: 正しい結果に近い出力結果を生成する
再現性と移植性: 異なる実行、異なるビルドオプションのセット、異なるコンパイラー、異なるプラットフォーム、異なるアーキテクチャーを通して、一貫している結果を生成する
パフォーマンス: 高速で効率的なコードを生成する
アプリケーションの目標に基づいて、これらの要素のトレードオフを行う必要があります。例えば、3D グラフィック・エンジンを開発していれば、パフォーマンスが最も重要な考慮事項であり、再現性と精度は、2 番目になるかもしれません。
インテル® コンパイラーは、特定の目標に合わせてアプリケーションをチューニングできるコンパイラー・オプションを提供します。オプションには、-fp-model (Linux* および OS X*) または /fp (Windows*) などの浮動小数点固有のものや、-fimf-max-error (Linux* および OS X*) または /Qimf-max-error (Windows*) オプションなどの高速ですが精度の低いものがあります。 コンパイラーは、指定されたコンパイラー・オプションによって、異なる最適化をコードに適用します。プログラミング目標を調整し、適切なコンパイラー・オプションを選択して、各要素間のトレードオフを行ってください。一部のオプションは、呼び出される演算ルーチンの種類に影響します。libirc、libm、および svml ライブラリーの多くのルーチンは、互換マイクロプロセッサーよりもインテル製マイクロプロセッサーでより高度に最適化されます。
次にコード例を示します。
float t0, t1, t2;
...
t0=t1+t2+4.0f+0.1f;
精度を優先して、-fp-model extended (Linux* および OS X*) または /fp:extended (Windows*) オプションを指定すると、コンパイラーは次のアセンブリー・コードを生成します。
fld DWORD PTR _t1
fadd DWORD PTR _t2
fadd DWORD PTR _Cnst4.0
fadd DWORD PTR _Cnst0.1
fstp DWORD PTR _t0
上記のコードは、ターゲット・プラットフォームで可能な最高の仮数の精度を利用するため、最大限の精度をもたらします。しかし、x87 スタックの管理による負荷のため、パフォーマンスが低下する可能性があります。また、同等の拡張精度型を持たない他のプラットフォームで再現できない結果を招くかもしれません。
再現性と移植性を優先して、-fp-model source (Linux* および OS X*) または /fp:source (Windows*) オプションを指定すると、コンパイラーは次のアセンブリー・コードを生成します。
movss xmm0, DWORD PTR _t1
addss xmm0, DWORD PTR _t2
addss xmm0, DWORD PTR _Cnst4.0
addss xmm0, DWORD PTR _Cnst0.1
movss DWORD PTR _t0, xmm0
上記のコードは、元の順序の計算を維持し、明確な IEEE の単精度型をすべての計算に使用することにより、最大限の移植性をもたらします。ただし、中間式の丸め誤差が拡張精度に比べて多いため、最初の例ほどの精度はありません。また、1.4.0f + 0.1f の事前計算を活用しないため、パフォーマンスも最大ではありません。
パフォーマンスを優先して、-fp-model fast (Linux* および OS X*) または /fp:fast (Windows*) オプションを指定すると、コンパイラーは次のアセンブリー・コードを生成します。
movss xmm0, DWORD PTR _Cnst4.1
addss xmm0, DWORD PTR _t1
addss xmm0, DWORD PTR _t2
movss DWORD PTR _t0, xmm0
上記のコードは、インテル® SSE 命令を使用し、4.0f + 0.1f を事前計算することにより、最大限のパフォーマンスをもたらします。 ただし、中間式の丸め誤差が多いため、最初の例ほどの精度はありません。また、4.0f + 0.1f を事前計算するために加算の順序を変更するため、2 つ目の例のように再現性のある結果をもたらしません。すべてのコンパイラー、すべてのプラットフォーム、すべての最適化レベルで同じように加算の再配置が行われるとは限りません。
多くのアプリケーションでは、このような考慮事項がより複雑になるでしょう。
高速ですが精度の低いオプションは、算術関数の精度を制御し、インテルの算術ライブラリーによるパフォーマンス/精度のトレードオフを簡単に利用できるようにします。コマンドライン・インターフェイスで、すべての算術関数または選択した算術関数セットの精度を、high、medium、low よりも細かいレベルで指定できます。
コンパイラーが算術ライブラリーから適切な関数実装を選択するのに使用する関数属性のセットを指定することで、精度を制御します。属性 max-error を使用する例を以下に示します。 例えば、次のオプションを使用します。
-fimf-max-error=2
これは、すべての single、double、long double、および quad の関数の相対誤差を 2 ulps (unit in the last place: 最後の桁の単位) に指定します。
sin 関数の精度を 12 ビットにする場合は、次のように指定します。
–fimf-sin-accuracy-bits=12
sin 関数の相対誤差を 10 ulps、コンパイルするソースファイルで呼び出される他の算術関数の相対誤差を 4 ulps にする場合は、次のように指定します。
-fimf-sin-max-error=10 -fimf-max-error=4
インテル® コンパイラーは max-error 属性のデフォルト値を、/fp オプションと /Qfast-transcendentals 設定によって定義します。 /fp:fast モード、または高速で少し精度が低い算術関数が /Qfast-transcendentals- で明示的に有効になると、インテル® コンパイラーは呼び出しに対して max-error=4.0 を設定します。 それ以外の場合は、max-error=0.6 を設定します。