-O、-qoptimize

説明

コンパイル中にコードを最適化するかどうかを指定し、最適化する場合は、最適化のレベルを指定する。

構文

構文図を読む構文図をスキップする          .-nooptimize-------------.
>>-+- -q--+-optimize--+----------+-+-+-------------------------><
   |                  '-=--+-0-+-'   |
   |                       +-2-+     |
   |                       +-3-+     |
   |                       +-4-+     |
   |                       '-5-'     |
   +- -O0----------------------------+
   +- -O-----------------------------+
   +- -O2----------------------------+
   +- -O3----------------------------+
   +- -O4----------------------------+
   '- -O5----------------------------'
 

最適化の設定は以下のとおりです。

-O0
-qnooptimize
-qoptimize=0
定数のフォールディングやローカルの共通副次式の除去など、高速でローカルな最適化のみを実行します。

この設定は、-qnostrict_induction を明示的に 指定していない限り、 -qstrict_induction を暗黙指定します。

-O
-qoptimize
コンパイル速度とランタイム・パフォーマンスの最良の組み合わせであるとコンパイラー開発者が考えた最適化を実行します。最適化は製品のリリースごとに異なる場合があります。特定のレベルの最適化が必要な場合は、適切な数値を指定してください。

この設定は、-qstrict_induction または -qnostrict によって明示的に否定されていない限り、-qstrict-qnostrict_induction を暗黙指定します。

-O2
-qoptimize=2
-O と同じ。
-O3
-qoptimize=3
メモリー、コンパイル時間、 またはこれら両方を大量に消費する追加の最適化を実行します。 このレベルは、 コンパイル・リソースの最小化よりも実行時の向上を図りたい場合に有効です。

-O3-O2 レベルの最適化を適用しますが、時間とメモリーの制限は無制限になります。また -O3 は、プログラムのセマンティクスを若干変更する可能性のある、より高度で積極的な最適化を実行します。コンパイラーは、-O2 ではこれらの最適化から保護します。

-O3
-qoptimize=3 (続き)
-O3 を指定したときに実行される積極的な最適化は以下の通りです。
  1. 積極的なコードの動き、および例外を発生させる可能性がある計算のスケジューリングが許可されます。

    ロードおよび浮動小数点計算は、このカテゴリーに分類されます。 この最適化が積極的なのは、 命令がプログラムの実際のセマンティクスに一致していない可能性がある ときに命令を実行する 実行パスに、 それらの命令を配置することがあるためです。

    例えば、 ループ内で不変の浮動小数点計算がループを通るいくつかのパスで見つかっても、 すべてのパスを通らない場合は、その計算が例外を発生させる場合があるため、 -O2 では移動されません。-O3 では、 例外が発生することが確実ではないので、コンパイラーはその計算を移動させます。ロードの動きについても同じことが言えます。 ポインターを介したロードが移動されることはありませんが、 静的またはスタック基底レジスターを介さないロードは、 -O3 では移動可能であると見なされます。 プログラムに 10 個のエレメントがある静的配列 a の宣言を入れて、 a[60000000003] をロードすると、 セグメント違反が発生する可能性があるため、一般に、 -O2 でのロードは絶対に安全であるとはいえません。

    同様の概念がスケジューリングにも適用されます。

    例:

    以下の例において、-O2 では、 b+c の計算は、以下の 2 つの理由でループからは移動されません。

    • 浮動小数点演算であるため危険と見なされる。
    • ループを通るすべてのパスで発生するわけではない。

    -O3 では、コードは移動されます。

          ...
        int i ;
        float a[100], b, c ;
        for (i = 0 ; i < 100 ; i++)
         {
         if (a[i] < a[i+1])
          a[i] = b + c ;
         }
          ...
  2. IEEE 規則への準拠が緩和されます。

    -O2 では、ある特定の最適化は実行されません。 これは、そのような最適化によって、結果がゼロの場合に誤った符号が生成されたり、 なんらかのタイプの浮動小数点例外を発生させる可能性のある算術演算が除去されるためです。

    例えば、X + 0.0 は X には折り畳まれません。 これは、IEEE 規則では -0.0 + 0.0 = 0.0 であり、 これは -X になるからです。他の例として、最適化の中には、 符号が誤ったゼロの結果を生成する最適化を実行するものもあります。 例えば、X - Y * Z の結果は -0.0 になります。 これは、元の計算では 0.0 になります。

    ほとんどの場合、結果の相違はアプリケーションにとって重要ではないため、 -O3 ではこれらの最適化が許可されます。

  3. 浮動小数点式が書き換えられる場合があります。

    再配置によって共通副次式を抽出する機会が得られる場合などには、 a*b*c などの計算を a*c*b に書き換える場合があります。浮動小数点計算の再配置の別の例として、 除算を逆数による乗算で置き換えることが挙げられます。

  4. XL C/C++ のバージョン 8 以降、-O3 を指定すると、明示的に -qhot または -qhot=level=1 オプションを指定しない限り、-qhot=level=0 が暗黙指定されます。
-O3、-qoptimize=3 (続き)

  • -qfloat=rsqrt は、-O3 ではデフォルトで設定されます。
  • -qmaxmem=1 は、 -O3 ではデフォルトで設定され、最適化を実行するときにコンパイラーが必要なだけ多くのメモリーを使用できるようにします。
  • 組み込み関数は、-O3 では errno を変更しません。
  • 整数除算命令の最適化は、 -O3 であっても非常に危険であると見なされます。
  • デフォルトの -qmaxmem 値は、 -O3 では -1 です。
  • optimize オプションを -qflttrap オプションと一緒に指定したときのコンパイラーの振る舞いについては、-qflttrapを参照してください。
  • -qstrict および -qstrict_induction コンパイラー・オプションを使用して、 プログラムのセマンティクスを変更する可能性がある -O3 の影響をオフにすることができます。-qstrict-O3 と一緒に指定すると、-O2 で実行されるすべての最適化のほか、ループの最適化も呼び出されます。-qstrict コンパイラー・オプションへの参照は、-O3 オプションの前に指定することも、後に指定することもできます。
  • -O3 コンパイラー・オプションの後に -O オプションを指定すると、 -qignerrno がオンのままになります。
  • -O3-qhot=level=1 が有効な場合、コンパイラーはソース・コード内のすべての呼び出しを、同等の MASS ライブラリー関数、および可能であれば、ベクトル・バージョンへの呼び出しを持つ標準の数学ライブラリー関数に置換します。
-O4
-qoptimize=4
このオプションは -O3 と同じですが、以下の点が異なります。
  • コンパイルを行うマシンのアーキテクチャーに対して、 -qarch および -qtune オプションを設定する。
  • コンパイル・マシンの特性に最も適した -qcache オプションを設定する。
  • -qhot オプションが設定される。
  • -qipa オプションが設定される。

Note: -O-qcache-qhot-qipa-qarch、および -qtune オプションを後で設定すると、-O4 オプションによって暗黙指定された設定がオーバーライドされます。

-O5
-qoptimize=5
このオプションは -O4 と同じですが、以下の点が異なります。
  • -qipa=level=2 オプションを設定して、完全なプロシージャー間のデータ・フローおよび別名の分析を実行します。

注: -O-qcache-qipa-qarch、 および -qtune オプションを後で設定すると、 -O5 オプションによって暗黙指定された設定がオーバーライドされます。

-qoptimize... は、-qopt... に省略できます。 例えば、-qnoopt-qnooptimize と同等です。

最適化のレベルを上げても、 追加の分析によって最適化の機会がさらに検出されるかどうかに応じて、 さらにパフォーマンスが向上する場合と向上しない場合があります。

最適化を伴うコンパイルでは、 他のコンパイルよりも多くの時間およびマシンのリソースが必要になる場合があります。

最適化によってステートメントが移動または削除される場合があるため、通常は、 デバッグ・プログラムのための -g フラグと一緒に最適化を指定しないでください。作成されるデバッグ情報が正確でなくなる場合があります。

myprogram.C をコンパイルして最適化するには、以下のように入力します。

xlc++ myprogram.C -O3

関連情報