浮動小数点アプリケーションのプログラミング・トレードオフ

一般に、浮動小数点アプリケーションのプログラミングの目標は、次のカテゴリーに分けられます。

アプリケーションの目標に基づいて、これらの要素のトレードオフを行う必要があります。例えば、3D グラフィック・エンジンを開発していれば、パフォーマンスが最も重要な考慮事項であり、再現性と精度は、2 番目になるかもしれません。

インテル® コンパイラーは、-fp-model (Linux* および Mac OS* X) または /fp (Windows*) オプションのような適切なコンパイラー・オプションを提供します。このようなオプションを使用し、特定の目標に合わせてアプリケーションをチューニングできます。コンパイラーは、指定されたコンパイラー・オプションによって、異なる最適化をコードに適用します。次にコード例を示します。

float t0, t1, t2;

...

t0=t1+t2+4.0f+0.1f;

精度を優先して、-fp-model extended (Linux および Mac 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 および Mac 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 および Mac 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 つめの例のように再現性のある結果をもたらしません。すべてのコンパイラー、すべてのプラットフォーム、すべての最適化レベルで同じように加算の順序変更が行われるとは限りません。

多くのアプリケーションでは、このような考慮事項がより複雑になるでしょう。プログラミング目標を調整し、適切なコンパイラー・オプションを選択して、各要素間のトレードオフを行ってください。