O、optimize

C に適用 C++ に適用

目的

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

構文

          .-nooptimize-------------.
>>-+- -q--+-optimize--+----------+-+-+-------------------------><
   |                  '-=--+-0-+-'   |
   |                       +-2-+     |
   |                       +-3-+     |
   |                       +-4-+     |
   |                       '-5-'     |
   +- -O0----------------------------+
   +- -O-----------------------------+
   +- -O2----------------------------+
   +- -O3----------------------------+
   +- -O4----------------------------+
   '- -O5----------------------------'
 
 

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


-O0
-qNOOPTimize
-qOPTimize=0
定数の折り込みおよびローカルな共通部分副次式の除去などの、高速でローカルな最適化のみを実行します。

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

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

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

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

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

-O3 を指定して -qstrict オプションを使用し、プログラムのセマンティクスを変更する可能性がある積極的な最適化をオフにしてください。 -qstrict-O3 とともに指定すると、 -O2 で実行されるすべての最適化に加えて、さらにループの最適化も行われます。-qstrict コンパイラー・オプションは、-O3 オプションの後に指定しないと無視されます。

-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 に書き換える場合があります。浮動小数点計算の再配置の別の例として、除法を逆数による乗算で置き換えることが挙げられます。

-O3 -qOPTimize=3 (続き)

  • -qfloat=rsqrt は、デフォルトでは -O3 で設定されます。
  • -qmaxmem=1 は、デフォルトでは -O3 で設定され、コンパイラーは最適化を実行するときにメモリーを必要なだけ使うことができます。
  • 組み込み関数は、 -O3 では errno を変更しません。
  • 整数除法命令の最適化は、 -O3 であっても非常に危険であると見なされます。
  • デフォルトの -qmaxmem 値は、 -O3 では -1 です。
  • optimize オプションを flttrap オプションと一緒に指定したときのコンパイラーの動きについては、-qflttrap を参照してください。
  • -qstrict および -qstrict_induction コンパイラー・オプションを使用して、プログラムのセマンティクスを変更する可能性がある -O3 の影響をオフにすることができます。 -qstrict コンパイラー・オプションへの参照は、-O3 オプションの前後いずれに現れてもかまいません。
  • -O3 コンパイラー・オプションの後に、 -O オプションを指定すると、 -qignerrno がオンのままになります。
-O4
-qOPTimize=4
このオプションは -O3 と同じですが、以下の点が異なります。
  • コンパイルを行うマシンのアーキテクチャーに対して、 -qarch および -qtune オプションを設定する。
  • コンパイル・マシンの特性に最も適した -qcache オプションを設定する。
  • -qhot オプションが設定される。
  • -qipa オプションが設定される。

注: -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

関連参照

IBM Copyright 2003