インテル® C++ コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス
アプリケーションのパフォーマンス向上は、たとえデフォルトの最適化レベルであっても、インテル® C++ コンパイラーの重要な目的です。多くの最適化で、コンパイル時の定数式の評価、ループからの不変式のホイスティング、式評価の順序の変更など、アプリケーションの浮動小数点動作に影響を与える変換が行われます。このような最適化処理は通常、コンパイラーが、可能な限り最も効率の良いコードを生成するのに役立ちます。しかし、最適化はアプリケーションの浮動小数点の要件に反することがあります。
いくつかの最適化は、C および C++ の ANSI 規格や ISO 規格の厳密な解釈とは一致していません。このような最適化処理は、丸めによる差異や若干の変異により、ANSI 準拠の結果とは精度が異なる浮動小数点結果になる場合があります。
インテル® C++ コンパイラーでは、-fp-model オプション (Linux* および macOS*) や /fp オプション (Windows*) が提供されており、アプリケーションをビルドする際に実行する最適化を制御することができます。このオプションにより、次のコンパイラー規則を指定することが可能です。
安全な値: 結果に影響を与える変換を行うかどうかを指定します。例えば、SAFE モードでは、コンパイラーは x/x を 1.0 には変換しません。これは、ランタイム時の x の値がゼロか NaN である可能性があるためです。UNSAFE モードはデフォルトです。
浮動小数点式の評価: 中間式の丸めを処理する方法を指定します。例えば、倍精度が指定されたとき、コンパイラーは、t0=4.0f+0/1f+t1+t2; を t0=(float)(4.1+(double)t1+(double)t2); として解釈します。
浮動小数点の縮約: 対応するプロセッサーで FMA (Fused Multiply-Add) 命令を行うかどうかを指定します。有効な場合は、コンパイラーは乗算/加算の組み合わせに対して FMA 命令を生成します。無効な場合は、コンパイラーは中間式の丸めにより乗算/加算命令を個別に生成する必要があります。
浮動小数点環境アクセス: プログラムが浮動小数点環境にアクセスする可能性を、デフォルトの浮動小数点制御設定を変更したり、浮動小数点ステータスフラグを読み込むことにより、考慮させるかどうかを指定します。デフォルトでは無効です。-fp-model:strict オプション (Linux* および macOS*) または /fp:strict オプション (Windows*) を使用して有効にできます。
厳密な浮動小数点例外: 浮動小数点演算により例外を生成する可能性を考慮させるかどうかを指定します。デフォルトでは無効です。-fp-model:strict (Linux* および macOS*) または /fp:strict (Windows*)、あるいは -fp-model:except (Linux* および macOS*) または /fp:except (Windows*) で有効にできます。
次の例について考えてみます。
double a=1.5; int x=0; ... __try { int t0=a; // raises inexact x=1; a*=2; } __except(1) { printf("SEH Exception: x=%d\n", x); }
厳密な浮動小数点例外を指定しない場合、結果は SEH Exception: x=1 です。厳密な浮動小数点例外を指定する場合、結果は SEH Exception: x=0 です。
次の表は、コンパイラー規則と最適化におけるさまざまなオプションのキーワードの影響を説明しています。
キーワード |
安全な値 |
浮動小数点式の評価 |
浮動小数点の縮約 |
浮動小数点環境アクセス |
厳密な浮動小数点例外 |
---|---|---|---|---|---|
precise |
安全 |
それぞれ異なる |
〇 |
× |
× |
strict |
安全 |
それぞれ異なる |
× |
〇 |
〇 |
consistent |
安全 |
それぞれ異なる |
× |
× |
× |
fast=1 (デフォルト) |
安全ではない |
不明 |
〇 |
× |
× |
fast=2 |
危険 |
不明 |
〇 |
× |
× |
except |
影響なし |
影響なし |
影響なし |
影響なし |
〇 |
except キーワードを Unsafe モードで指定するのは不正です。
アプリケーションの目的に応じて、さまざまなコンパイラー・オプションとキーワードのセットを選択して、特定の最適化を有効または無効にし、望ましい結果を得るようにできます。