04.04.2013 Views

Meet the HP Superdome servers - 日本HP (ヒューレット・パッカード) - HP

Meet the HP Superdome servers - 日本HP (ヒューレット・パッカード) - HP

Meet the HP Superdome servers - 日本HP (ヒューレット・パッカード) - HP

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Itanium ベース アプリケーションの最適化<br />

バージョン 1.4<br />

White paper<br />

目次<br />

はじめに ...................................................................................................................................................2<br />

最適化の 6 つのレベル ...............................................................................................................................2<br />

レベル ゼロ ...........................................................................................................................................2<br />

レベル 1................................................................................................................................................2<br />

レベル 2................................................................................................................................................2<br />

レベル 2 -ipo .........................................................................................................................................3<br />

レベル 3................................................................................................................................................3<br />

レベル 4(レベル 3 -ipo) ..........................................................................................................................4<br />

-ipo を使用したプロシージャ間の最適化.........................................................................................................5<br />

高度な最適化オプションとプラグマ ................................................................................................................7<br />

積極的最適化の有効化 ...........................................................................................................................7<br />

最適化時のコンパイル時間制限の解除......................................................................................................7<br />

最適化コードのサイズを制限 ....................................................................................................................7<br />

スケジューリング モデルの制御 ................................................................................................................8<br />

浮動小数点最適化の制御........................................................................................................................8<br />

データ割り当ての制御 .............................................................................................................................9<br />

シンボル バインディングの制御...............................................................................................................10<br />

その他の最適化機能の制御...................................................................................................................11<br />

プロファイル ベースの最適化 .....................................................................................................................15<br />

計測用実行ファイルの作成 ....................................................................................................................15<br />

プロファイル用データの収集 ...................................................................................................................15<br />

プロファイル ベースの最適化の実行........................................................................................................15<br />

プロファイル データ ファイルの保守 .........................................................................................................15<br />

Itanium と PA-RISC のプロファイル ベース最適化の相違..............................................................................16<br />

1


はじめに<br />

<strong>HP</strong> Itanium ベースのオプティマイザは、コードを変換し、Itanium TM ベースの <strong>HP</strong>-UX システム上でのコードの実行効率を<br />

高めます。オプティマイザは、アプリケーションのパフォーマンスを大幅に改善します。最適化のレベルが上がるほど実<br />

行される解析の複雑さが増すため、コンパイル時間とメモリ消費量は増大します。<br />

このドキュメントで取り扱う内容は、次のとおりです。<br />

• 最適化の 6 つのレベル<br />

• プロシージャ間の最適化<br />

• 高度な最適化オプションとプラグマ<br />

• プロファイル ベースの最適化<br />

最適化の 6 つのレベル<br />

最適化には、6 つのレベルがあります。各レベルは、下位レベルの上位集合となっています。追加のパラメータを使用し<br />

て、最適化の程度、コンパイル時間、生成される実行可能プログラムのサイズを制御できます。<br />

レベル ゼロ<br />

+O0<br />

説明:<br />

• 単純なレジスタ割り当て<br />

• 単純なスケジューリング(1 命令/サイクル、1 バンドル/サイクル)<br />

• ほとんどの場合、使用しないこと<br />

利点:<br />

コンパイル時間は最速。ただし、生成コードの質の点から、この最適化レベルを使用しないことを強く推奨します。<br />

レベル1<br />

+O1(デフォルト)<br />

説明:<br />

• 共通の部分式の削除、定数の畳み込み、ロード/ストアの削除など、単一基本ブロックを対象とするローカルな最適<br />

化<br />

• レベル ゼロより高度な命令スケジューリング<br />

• ローカル スカラー、C/C++ のフォーマル スカラーに対するレジスタ プロモーション<br />

• C++で、変換ユニット内の逆方向(backward) 呼び出しのインライン化<br />

利点:<br />

• +O0 より格段に高速なコードを生成、かつ、+O2 よりコンパイル時間が高速<br />

• コードのデバッグ性を維持<br />

レベル2<br />

+O2 または–O<br />

説明:<br />

• レベル 1 の最適化に加えて、関数全体を対象とする最適化を実行<br />

• 高速なコンパイル時間とパフォーマンス向上を保証するため、調整した経験則に基づいて、モジュール内インライン化<br />

を実行<br />

• グルーバル最適化、コード モーション(移動)、レジスタ プロモーションを実行<br />

• データ プリフェッチ、合計の削減(sum reduction)、スカラー置換、強度の低減(strength reduction)、アンローリング、イ<br />

ンクリメント後統合(post-increment syn<strong>the</strong>sis)など、ループ最適化を実行<br />

2


• FMA 命令への統合、デッド コード削除など、追加の最適化を実行<br />

• 該当するライブラリ呼び出しに対応するシステム ヘッダを組み込む場合、特定ライブラリ コードの呼び出しの最適化<br />

を実行。たとえば、sqrt、sin、cos の呼び出し、およびメモリ コピー、比較の呼び出しのインライン化を実行できま<br />

す。ライブラリ呼び出しのコモン化も実行できます。<br />

また、オプティマイザは、Itanium のアーキテクチャの特徴を活かして、アプリケーションの並列処理を命令レベルで改善<br />

するいくつかの変換手法を採用しています。たとえば、スケジューラは、プレディケーション、制御の投機的実行(control<br />

speculation)、データの投機的実行(data speculation)などの手法を実行します。プレディケーションを採用することで、<br />

分岐命令を削除しながら、複数の実行パスを同時に実行できる、条件付き実行命令に制御フローを変換できます。また、<br />

投機的実行により、開発者の指定した順序よりも早い段階でコードを実行できます。<br />

(前段で説明した)こうしたスケジューリング手法を効率的、効果的に実行するために、コードを区画に分割し、それぞれ<br />

1 ユニットとして最適化します。最も内側のループについては、効率的なスケジュールのために特殊な分岐命令やロー<br />

テーション レジスタを利用して、可能な限りソフトウェア パイプライン化します。プレディケーションにより、制御フローを<br />

持つループもソフトウェア パイプライン化することができます。また、(制御、データ)両タイプの投機的実行は、モジュー<br />

ロ・スケジューリング ループもサポートします。<br />

利点:<br />

• コードの最適化、マシン リソースの効率的利用、Itanium アーキテクチャの特長の活用により、レベル 1 に比較して、<br />

著しく高速なコード<br />

• 非数値計算アプリケーションを 50%以上改善可能<br />

• ループ集約的数値計算アプリケーションでは、データ プリフェッチ、ソフトウェア パイプライン化などの最適化により、<br />

それ以上の高速化を達成<br />

レベル2 -ipo<br />

+O2 -ipo または –O-ipo<br />

説明:<br />

• レベル 2 の最適化に加えて、アプリケーション プログラム全体を対象とする最適化を実行<br />

• 別名解析、クロス モジュール インライン化、デッド変数とデッド関数の削除、変数プライベート化、ショートデータの最<br />

適化、コール スタブ インライン化など、プロシージャ間の最適化をリンク時に実行<br />

• 動的 PBO データが利用できる場合 (+Oprofile=use)、プログラム全体モードで、間接呼び出しプロモーションを実行<br />

• 数学ライブラリ ルーチンの大きなセットをユーザー コード内にインライン化<br />

• 詳細については、後出のプロシージャ間の最適化の項目を参照<br />

利点:<br />

• 効率的なエイリアス情報とインライン化で、レベル 2 を超える最適化を実行<br />

• 多数の間接呼び出しや仮想関数呼び出しのあるアプリケーションでは、間接呼び出しプロモーションにより、大きな利<br />

益を享受<br />

• データ最適化により、キャッシュと TLB 動作を改善<br />

• コード最適化により、命令数を削減<br />

レベル3<br />

+O3<br />

説明:<br />

• レベル 2 の最適化に加えて、単一ファイル内のすべての関数にわたる最適化を実行<br />

• 同じファイル内の関数のインライン化とクローン化<br />

• ループ変換(たとえば、交換(interchange)、融合(fusion)、アンローリング)など、高レベルの最適化を実行<br />

• 数学ライブラリ ルーチンの大きなセットをユーザー コード内にインライン化<br />

• 単純なコピー ループを識別し、最適化されたメモリ コピー ルーチン呼び出しに置換<br />

• 単純に手動でアンロールしたループを識別し、それを再ロール。後続のループ オプティマイザで、特定プラットフォー<br />

ム用に効率的なアンローリングの決定ができるようにする<br />

3


利点:<br />

レベル 2 より高速なコードを生成可能です。ループ変換の効果の大きい数値コードや、インライン化から恩恵を受ける、<br />

同じファイル内の小さな関数を頻繁に呼び出すコードまたは数学ライブラリ関数を呼び出すコードについて、特に当ては<br />

まります。<br />

レベル4(レベル3 -ipo)<br />

+O4 または +O3 -ipo<br />

説明:<br />

• レベル 3 の最適化に加えて、アプリケーション プログラム全体にわたる最適化を実行<br />

• リンク時にプロシージャ間の最適化を実行。要約は「レベル 2 -ipo」を参照<br />

利点:<br />

• プロシージャ間の最適化は、アプリケーションのパフォーマンスを総体的に改善 (「レベル 2 –ipo」を参照)<br />

• 効率的なエイリアス情報とインライン化により、ループ変換を改善し、追加のループ変換が可能<br />

4


-ipo を使用したプロシージャ間の最適化<br />

<strong>HP</strong> ハイレベル オプティマイザには、プロシージャ間オプティマイザ、ハイレベル ループ オプティマイザ、スカラー オプテ<br />

ィマイザが含まれています。<br />

プロシージャ間オプティマイザ(Interprocedural Optimizer)は、最適化レベル 2 またはそれ以上のレベルで -ipo オプシ<br />

ョンを付ける(たとえば+O2 -ipo)ことにより有効になります。最適化レベル 4(オプション +O4)は、暗黙に -ipo を含<br />

んでいます。<br />

ハイレベル ループ オプティマイザは、最適化レベル 3 またはそれ以上(オプション +O3 と +O4)で、有効です。このオ<br />

プティマイザは、ループ交換(interchange)、ループ分散(distribution)、ループ融合(fusion)、パラレル化を実行します。<br />

ハイレベル スカラー オプティマイザは、他のハイレベル最適化とともに有効になります。このオプティマイザは、制御フ<br />

ロー最適化、基本ブロックのクローン化のほか、式の単純化と正規化(canonicalization)、SSA ベースのデッドコード削<br />

除、コピーの伝播、定数の伝播を実行します。<br />

ここでは、プロシージャ間オプティマイザの利点を中心に説明します。<br />

オプション -ipo は、アプリケーションのソース ファイルの一部または全部、どちらのコンパイル時にも使用できます。一<br />

部のモジュール群に -ipo を付けてコンパイルすると、それらのファイル間でのみ、モジュール間の最適化が実行されま<br />

す。このモードでは、コンパイラにより IPO 時にアプリケーションの一部のみが解析されることになり、コンパイラは、アプ<br />

リケーションの残り部分の最適化が困難になります。このため、最適化の機会が一部失われる可能性があります。<br />

最大のパフォーマンスを求めるときは、-ipo を付けて、アプリケーションのソース ファイルの全部をコンパイルするのが<br />

有益です。このモードを、プログラム全体モード(whole program mode)と呼んでいます。このモードで、コンパイラは、<br />

アプリケーションの正確な解析を実行でき、パフォーマンスの改善につながります。<br />

ハイレベル オプティマイザは、PBO 情報を活用することができるため、PBO (オプション +Oprofile=use) と組み合わせ<br />

て使用すると一層効果的です。たとえば、PBO データは、関数インライン化を改善します。PBO データは、間接呼び出し<br />

側で、最も可能性の高い呼び出し先を明らかにでき、これにより、ハイレベル オプティマイザは、間接呼び出しをテスト<br />

呼び出しおよび直接呼び出しに変換できます。<br />

プロシージャ間の最適化は、現在、次のかたちでアプリケーションのパフォーマンスに利益をもたらしています。<br />

• メモリ参照と関数引数のプロシージャ間解析は、多種類の最適化に対応し、改善します。たとえば、レジスタ プロモー<br />

ションなど、ローレベル オプティマイザで追加の最適化機会を生み出します。<br />

次の例を考えてください:<br />

void foo(int *x,int *y)<br />

{<br />

... = *x; //load1<br />

*y = ... //store1<br />

... = *x; //load2<br />

}<br />

ポインタ x と y について追加の知識がなければ、コンパイラは、ストア (store 1) がポインタ x の内容を上書きする可<br />

能性があるため、2 つ目のロード命令 (load2) を実行しなければなりません。<br />

プロシージャ間解析の結果として、x と y がエイリアスしない(同じメモリ ロケーションを指さない)ことをコンパイラが判<br />

定できれば、コンパイラは、*x の値をレジスタにプロモートし、このレジスタを再使用できます (load 2)。<br />

• 関数インライン化は、呼び出しオーバヘッドの削減、実行コードの局所性の改善、分岐数の削減など、一般的な利益<br />

を提供します。さらに重要なのは、インライン化によりスケジュール対象となる命令群のスコープが拡張されるために、<br />

より効率的な最適化が行えるようになるということです。<br />

このコンパイラ リリースでは、非常に大規模なアプリケーションに対応するため、インライン化フレームワークが再設<br />

計されています。新しいフレームワークは、斬新で超高速の基盤アルゴリズムを使用し、インライン化決定用に新しい<br />

精巧な経験則を採用しています。<br />

注記: このインライン化エンジンは、+O2 におけるモジュール内インライン化でも利用されます。この最適化レベル<br />

では、インライン化の経験則のレベルを下げて、パフォーマンス向上と高速なコンパイル時間を保証します。<br />

5


• 間接呼び出しプロモーションを有効にして、呼び出し全体のグラフを作成し、間接呼び出しをテスト呼び出しおよび直<br />

接呼び出しに変換します。PBO データが存在する場合、アプリケーションの特性に応じて、大幅なアプリケーションの<br />

高速化が期待されます(実際に特定のアプリケーションで、最大 20%の改善を観測しました)。<br />

• ハイレベル オプティマイザは、デッド変数の削除により、参照されないグルーバル変数と静的変数を削除し、アプリケ<br />

ーションに要求されるメモリ総量を削減できます。<br />

• オプティマイザは、割り当てられてはいるが一度も使用されないグルーバル変数、静的変数、ローカル変数を識別し<br />

て、(追加のデッド変数を生成する可能性のある)デッド コードを削除します。<br />

• モジュール内でしか参照されないグルーバル変数の変換を通じて、ハイレベル オプティマイザは、シンボルをプライ<br />

ベート シンボルに変換し、このモジュール内からのアクセスのみに限定します。これにより、ローレベル オプティマイ<br />

ザには、この変数への参照を最適化するうえで大きな自由が与えられます。<br />

• デッド関数の削除(一度も呼び出されない関数)と冗長関数の削除(たとえば重複するテンプレート インスタンス生成)<br />

は、ワーキング セットの数を減らすことで、コンパイル時間の短縮や、クロス モジュール インライン化の効果の改善<br />

に役立ちます。また、アプリケーションの合計コード サイズが縮小するため、キャッシュ ミス、ページ ミスの発生も少<br />

なくなります(パフォーマンスの改善につながります)。<br />

• ショートデータの最適化。ショートデータ領域に割り当てられたグルーバル データおよび静的データへのアクセス シ<br />

ーケンスが効率化されます。プログラム全体モード (-ipo) で、コンパイラは、正確な解析を実行して、グルーバル デー<br />

タおよび静的データがショートデータ領域に収まるかどうか判定し、収まるときは、その領域にデータを配置します。デ<br />

ータが収まらないときは、コンパイラは、最も安全なショートデータサイズ閾値を判定して、最大量のデータ アイテム<br />

が効果的に割り当てられるようにします。<br />

注記: これは、IPO の利点です。これ以外の最適化レベルでは、+Oshortdata オプションを使用することで、同様の<br />

最適化を有効にできます。-ipo オプションは、最適のショートデータ閾値を引き出します。<br />

• 外部関数(バイナリで常駐しない関数)の呼び出しについて、リンカは、小さな呼び出しスタブを導入します。コンパイラ<br />

は、関数呼び出しが外部関数呼び出しであることを認識すると、呼び出しスタブをインライン化でき、これによりパフォ<br />

ーマンスが改善します。<br />

<strong>HP</strong> コンパイラは、関数が外部関数であることを示すプラグマ (#pragma extern) で関数プロトタイプに注釈付けするメ<br />

カニズムをサポートしています。コンパイラ オプション -minshared を使用すると、コンパイラは呼び出しスタブのインラ<br />

イン化を実行できます。<br />

-ipo を指定したプログラム全体モードでは、これは一切必要ありません。このモードでは、コンパイラは、どの関数が<br />

アプリケーションにより定義され、どの関数が外部関数かを認識しており、それに応じて、自動的に関数にマークを付<br />

けます。<br />

また、プロシージャ間解析フェーズは、追加のソースの問題点を明らかにし、警告します。たとえば、変数が、異なるソー<br />

スファイル内で互換性のない属性で宣言されている場合です。<br />

プロシージャ間の最適化フレームワーク(最適化レベル +O2 以上で -ipo により有効)は、非常に大規模なアプリケーシ<br />

ョンに対応できるように、再設計されています。幸い、ユーザーの視点からはなにも変更はありません。既存のビルド プ<br />

ロセスを変更する必要もありません。IPO とコード生成がリンク時に実行されるため、リンク時間がかなり増すことがあり<br />

ます。<br />

プロシージャ間の最適化は、リンク時に実行されます。このフェーズの最後で、バイナリ ’be’ の複数の並列プロセスを<br />

呼び出して、コード生成とローレベル最適化フェーズが開始されます。並列 ’be’ プロセスのデフォルトの数は、マシン上<br />

のプロセッサの数に設定されています。この数を上書きするには、環境変数 "PARALLEL" を設定します。例:<br />

export PARALLEL=4<br />

6


高度な最適化オプションとプラグマ<br />

以降のセクションでは、最適化を有効にするためのいくつかのオプションについて説明します。<br />

積極的最適化の有効化<br />

+Ofast または -fast(Fortran では-fast はサポートされません)<br />

説明:<br />

[+O2 +Onolimit +Ofltacc=relaxed +FPD +DSnative +Oshortdata +Olibcalls のエイリアス]<br />

+O2 で、積極的最適化を有効にします。このオプションは、大多数のアプリケーションについて安全ですが、コンパイ<br />

ル時間の増加や、厳密な fp 精度が要求されるコードについては、出力が不正確になる可能性もあります。+Ofast<br />

では、+O2 で実行される最適化に加えて、下記を実行します。<br />

• 長いコンパイル時間を利用して、大きなプロシージャを完全最適化します。コンパイル時間が非線形に増加する可<br />

能性があります。<br />

• 追加の FP 最適化に対応します。浮動小数値の精度に影響する可能性があります。詳しくは、8 ページの<br />

+Onofltacc を参照してください。<br />

• ハードウェア上で、flush-to-zero 丸めモードを有効にします。<br />

• コンパイラが動作しているハードウェアに対応した、積極的なスケジューリングします。他の Itanium ベースの実装<br />

に対するパフォーマンス影響については配慮せずに、特定プロセッサ実装のリソースを対象にして、コードの最適<br />

化を試みます。<br />

• ソース コードに当該ライブラリ用の標準ヘッダ ファイルがインクルードされているかどうかに関係なく、特定ライブラ<br />

リ呼び出しを最適化シーケンスに置換します。標準ヘッダファイルがインクルードされている場合、デフォルトでこの<br />

最適化が実行されます。<br />

+Ofast は、fp の境界値を使用しない、安定した行儀の良い(well-behaved)コードで使用してください。<br />

+Ofast は、将来のリリースでは +O2 ではなく +O3 を含むことになるかもしれません。<br />

利益:<br />

• 特に、コンパイルしたシステムと同じタイプのシステム上でのみアプリケーションを実行する場合、大半のアプリケーシ<br />

ョンについて、パフォーマンスが安全に改善されます。<br />

• 安全で、アプリケーション パフォーマンスを大幅に改善できる最適化フラグが含まれているため、多数の最適化フラ<br />

グを指定する必要ありません。<br />

最適化時のコンパイル時間制限の解除<br />

+O[no]limit<br />

+Olimit=[min|default|none]<br />

(デフォルト +Olimit=default)<br />

デフォルトでは、オプティマイザは、非線形にコンパイル時間が増加するのを回避するため、+O2 以上で大きなプログ<br />

ラムの最適化する場合、適当な時間で処理するように調整されています。<br />

+Onolimit または +Olimit=none オプションを使用して、+O2 以上での最適化時間制限を解除できます。その<br />

場合、大きなプロシージャ群を完全に最適化できますが、非常に大きなプロシージャ群、とくに直線的コードの長いシ<br />

ーケンスを含むプロシージャでは、コンパイル時間が大幅に長くなる可能性があります。長いコンパイル時間を許容で<br />

きる場合は、+Onolimit により、かなりパフォーマンスが改善されます。<br />

+Olimit または +Olimit=min を使用して、コードの最適化に使用する時間を制限し、非線形にコンパイル時間<br />

が増加するのを完全に回避できます。<br />

最適化コードのサイズを制限<br />

+O[no]size (デフォルト +Onosize)<br />

+Osize オプションを使用して、+O2 以上でコード サイズを大幅に増やす最適化を無効にできます。ほとんどの最適<br />

化では、コード実行速度が改善され、コード サイズが同時に削減されます。しかし、一部の最適化では、コード サイ<br />

7


ズが大幅に増大することがあります。ループ アンローリングは、そうした最適化の一つです。これを無効化するには、<br />

+Osize を使用します。<br />

+Osize は、インライン化も無効にします。このオプションが、命令キャッシュ ミスの削減に役立つケースもあります。<br />

+Osize は、+Onolimit や +Ofast など他の最適化制御オプションと併用できます。<br />

スケジューリング モデルの制御<br />

+DS[blended|Itanium|Itanium2|native](デフォルト +DSblended)<br />

Itanium ベースの各実装間で、リソース制約、遅延、その他のスケジューリング基準に大きな相違が生じることもあり<br />

ます。最適化スケジューラは、現在、最初の 2 つの Itanium ベース実装、Intel Itanium と Intel Itanium 2 に対応してい<br />

ます。これらの実装について、それぞれ+DSItanium または +DSItanium2 を使用することにより、最適に動作す<br />

るコードをスケジューリングできます。<br />

しかし、コードの最適化は一度だけにして、そのコードをどちらの実装でもある程度良好に動作させたいという要求が<br />

あるでしょう。デフォルトの設定 +DSblended は、この要求に応えます。具体的に説明すると、+DSblended は、浮<br />

動小数点コードが Itanium で最適に動作し、Itanium 2 での性能低下は若干に留まるように、コードをスケジューリン<br />

グします。整数(または非浮動小数)コードは、Itanium 2 上でやや良好に動作するよう調整します。たとえば、<br />

+DSblended は、Itanium で発生するストールを最小化するため、Itanium の長い浮動小数遅延に合わせてスケジュ<br />

ールします。浮動小数点コードはモジューロ スケジューリング可能なループ内に格納されることが多いため、この長<br />

い遅延は、(モジューロ スケジューリング ループ内での追加ステージで発生する)小さな性能低下を伴う程度であり、<br />

Itanium 2 では耐えられる範囲です。<br />

コンパイルするプラットフォームが Itanium か Itanium 2 かにかかわらず、その実装用にコードを最速にスケジューリ<br />

ングするには、単純に +DSnative を使用します。Itanium の新しい実装がリリースされたときには、新しいターゲット<br />

が追加され、+DSblended により行われるスケジュールの内容が変更されることになります。<br />

浮動小数点最適化の制御<br />

+Ofltacc=[strict|default|limited|relaxed]<br />

+O[no]fltacc<br />

#pragma STDC FP_CONTRACT [ON/OFF/DEFAULT]<br />

期待されている浮動小数点計算の精度に違反しないように、浮動小数点コードの最適化を制御します。<br />

+Ofltacc=strict(またはそれと等値の +Ofltacc)を使用して、結果値を変える可能性のある最適化はすべて<br />

禁止されます。<br />

何も指定しない場合、または +Ofltacc=default 指定時に、値を変更する最適化で唯一許容されるのは、短縮<br />

(contraction)による統合です。これには、浮動小数点乗加算(fma)命令とその変化形が含まれます。この命令は、乗<br />

算と加算の 2 つの命令列の計算結果を変更してしまう可能性がありますが、乗算の計算結果が丸めの対象とならな<br />

いため、実際にはこの結果は統合を行う前よりも正確になります。<br />

Itanium 上では、この短縮がたいへん有利に働くことがあります。FP_CONTRACT プラグマを使用して、コードのブロッ<br />

ク単位で、短縮を有効、無効にできます。FP_CONTRACT OFF は、先行のプラグマまたは +Ofltacc=strict オ<br />

プションを上書きします。FP_CONTRACT ON には、先行の FP_CONTRACT OFF を取り消す以外の効果はなく、<br />

+Ofltacc=strict により上書きされます。+Ofltacc=limited は、短縮のほか、値を変更する他の最適化も<br />

有効にします。これらの最適化は、NaN (Not a Number)、無限大、ゼロ符号の伝播を防止できます。たとえば、<br />

0.0*x => 0.0 の最適化を実行することで、x が NaN、無限大または負の数のとき、NaN、無限大、ゼロ符号の<br />

伝播が防止されます。<br />

浮動小数点計算の最適化を最も積極的に行うには、+Ofltacc=relaxed(またはそれと等値の+Onofltacc)を<br />

使用します。たとえば、高速で効率的な浮動小数点除算シーケンスが、relaxed(緩い)の精度で有効化されます。<br />

また、+Ofltacc=relaxed で、浮動小数点計算を再結合する最適化が有効になります。たとえば、C または C++<br />

では、ループをアンローリングして、部分和を計算することにより浮動小数点加算の遅延を隠蔽する合計の削減(sum<br />

reduction)を、+Ofltacc=relaxed を使用して有効にできます(Fortran では、明示的括弧に違反しない再結合は<br />

常に正当であるため、この最適化は常に正当です)。<br />

+O[no]cxlimitedrange<br />

(C でのデフォルト +Onocxlimitedrange、Fortran でのデフォルト +Ocxlimitedrange)<br />

#pragma STDC CX_LIMITED_RANGE [ON/OFF/DEFAULT]<br />

8


アプリケーションが範囲外の浮動小数値に依存しないとき、このオプションを使用して、高速で複雑な算術シーケンス<br />

を取得できます。このオプションは、範囲外の浮動小数値(たとえば NaN、無限大)の発生および維持を行うかどうか<br />

を指定します。+Ocxlimitedrange の使用時、範囲外の浮動小数値は維持されない可能性があります。範囲限定<br />

のスイッチを有効にすると、高速で複雑な算術シーケンスを取得できます。オプションはグローバルですが、<br />

CX_LIMITED_RANGE プラグマは、特定のコード ブロックについて範囲限定の動作を有効にします。<br />

CX_LIMITED_RANGE ON は、+Onocxlimitedrange を上書きします。CX_LIMITED_RANGE OFF は、先行の<br />

CX_LIMITED_RANGE ON または+Ocxlimitedrange を取り消す以外の効果はありません。<br />

+O[no]fenvaccess (デフォルト +Onofenvaccess)<br />

#pragma STDC FENV_ACCESS [ON/OFF/DEFAULT]<br />

#pragma FLOAT_TRAPS_ON<br />

+Ofenvaccess は、非デフォルトの浮動小数点モード(たとえば、異なる方向への丸め、トラップの有効ど)下での動<br />

作、または、浮動小数点例外フラグが照会される場合の動作に影響を及ぼす可能性のある最適化を無効にします。<br />

このオプションは、FENV_ACCESS または FLOAT_TRAPS_ON プラグマのいずれかを使用して、ローカルに有効化す<br />

ることもできます。FENV_ACCESS ON と FLOAT_TRAPS_ON は、+Onofenvaccess を上書きします。<br />

FENV_ACCESS OFF には、先行の FENV_ACCESS ON、FLOAT_TRAPS_ON または+Ofenvaccess を取り消す<br />

以外の効果はありません。たとえば、+Ofenvaccess を指定すると、例外を発生させる可能性のある命令群からの<br />

デッド コード削除が防止されます。その結果、範囲外の計算結果を明示的にチェックするための浮動小数点数から整<br />

数へと変換する長いシーケンスが生成され、また、浮動小数点除算シーケンスも長くなります。<br />

+O[no]libmerrno<br />

(デフォルト +Onolibmerrno、-Aa を指定しない場合のデフォルト+Olibmerrno)<br />

libm 関数で errno のサポートを有効にします。+Olibmerrno オプションの下では、あまり最適化されていない<br />

バージョンの libm 関数が呼び出されます。この場合、libm 関数の呼び出しはもはや副作用なしでは行えないため、<br />

オプティマイザは、これらの呼び出しの最適化を実行すること(たとえば、同一入力で同じ libm 関数への呼び出しを<br />

合体すること)を禁止されます。<br />

-Aa を付けると、デフォルトは、+Olibmerrno になります。<br />

データ割り当ての制御<br />

+Olit=[none|const|all] (C でのデフォルト +Olit=const、C++ でのデフォル+Olit=all)<br />

Fortran ではサポートされません。<br />

読込み専用データ セクションにどの定数を配置するかを指定します。+Olit=none のとき、読込み専用メモリに定数<br />

は配置されません。+Olit=const のとき、ロード時または実行時に初期化を要しない定数修飾データが読込み専<br />

用メモリに配置されます。また、const char * が正当であるコンテキストで現われる文字列リテラルが読込み専用<br />

メモリに配置されます。+Olit=all のとき、すべての文字列リテラルが読込み専用メモリに配置される点以外は、<br />

+Olit=const の場合と同じ動作です。<br />

定数を読込み専用メモリに配置すると、同一文字列リテラルの合体により実行可能プログラムが小さくなり、マルチ<br />

ユーザー アプリケーションでデータ共有が促進されます。<br />

+Oshortdata[=n] (デフォルト n=8)<br />

Fortran ではサポートされません。<br />

ショートデータ領域に配置されるオブジェクトのサイズを制御します。n バイト、またはそれ以下のサイズのすべての<br />

オブジェクトがショートデータ領域に配置されます。ショートデータへの参照はすべて、(変換ユニット内でそのように定<br />

義されていない場合でも)データがショートデータ領域にあることを想定します。own ショートデータへのアクセスは、<br />

ショート領域を指すグローバルポインタからの相対アドレスを使用して実行されます。これは、ショート以外のデータま<br />

たは非 own データへのアクセス シーケンスよりも効率的です。Own データとは、現在のロード モジュールで定義済<br />

みと認識されている、静的に割り当てられたデータです。このデータには、静的データ、隠し(hidden)データ、保護<br />

(protected)データ、または変換ユニット内で参照の前に定義が現れているデータが含まれます。<br />

n の有効な値は、8~4,194,304 (4 MB) の範囲の 10 進値です。サイズを指定しないときは、すべてのデータがショ<br />

ートデータ領域に配置されます(合計サイズが 4MB を超えるとき、リンク エラーになります)。サイズのわからないア<br />

イテム(たとえば extern int a[];)については、+Oshortdata でサイズを指定していないときに限り、ショート<br />

領域を指すグローバルポインタからの相対アドレスでアクセスします。<br />

9


シンボル バインディングの制御<br />

以下のオプションを使用して、関数シンボルとデータ シンボルの両方のバインディングを制御できます。バインディング<br />

は、シンボルをどのように呼び出してアクセスするか、どのようにアクセス シーケンスを最適化するかを制御します。<br />

':filename' の形式で、'filename' は、スペース区切りまたは改行区切りのシンボル リストの入ったファイルを<br />

指します。オプションを誤って使用すると、各シンボルの可視定義数を変えることにより、およびロード時バインディング<br />

の実行方法を変えることにより、リンク時または実行時エラーのいずれかを引き起こす可能性があります。<br />

-Bprotected[=symbol[,symbol]*]<br />

-Bprotected:filename<br />

このオプションを使用して、データとコード シンボルの、最も最適化されたアクセス シーケンスを取得できます。名前<br />

の指定されたシンボルが、保護(protected)エクスポート クラス有として指定されます。どのシンボルも指定されない<br />

場合、参照されるが変換ユニット内に定義されていないものを含めて、すべてのシンボルが、保護エクスポート クラス<br />

有として指定されます。これは、該当するシンボルが代替されず、そのようなものとして最適化されることを意味します。<br />

たとえば、コンパイラは、コードとデータ参照の両方について、リンケージ テーブルをバイパスできます。コンパイラは<br />

また、参照を、ローカルに定義されたコードとデータ シンボルにバインドすることもできます。この結果、アクセス シー<br />

ケンスは、一層最適化されることになります。さらに、コンパイラは、保護シンボルの呼び出し前後の、gp の保存と復<br />

元を省略でき、pc 相対呼び出しを生成できます。呼び出しのターゲットがロード モジュールにとってローカルではない<br />

場合、リンカはエラーを生成します。ローカル定義シンボルには、これらの最適化が常に実行されます。ただし、–<br />

Bextern オプション リストにシンボルが指定されている場合は除きます。ローカルに定義されていないシンボルの<br />

最適化には、-Bprotected を使用します。<br />

シンボル リストなしで-Bprotected を指定すると、-Wl,-a,archive_shared も暗黙に指定され、リンカは、利<br />

用可能な場合は、共有ライブラリよりアーカイ ブライブラリを優先します。共有ライブラリへのアクセスよりアーカイブ<br />

ライブラリへのアクセスの方が高速であるため、結果として、パフォーマンス向上されます。<br />

共有ライブラリ呼び出しの実行時にリンカ エラーを回避するには、当該ルーチン用のシステム ヘッダ ファイルを組み<br />

込みます。シンボルは、代替可能として、システム ヘッダ内で適正にマークされています。ヘッダ ファイルを組み込ん<br />

でいない場合、シンボルが適正にマークされていないため、ロード モジュール内で定義されていないシンボルについ<br />

て、リンカは、エラーを生成します。このリンカ エラーは、シンボル呼び出し前後の、gp の保存と復元の省略など、不<br />

適切な最適化により起こる実行時エラーを防止します。適正なプラグマを使用して修飾しない場合、アプリケーション<br />

または、サード パーティの共有ライブラリとのリンク時に、同様の問題が発生する可能性があります。ライブラリ プロ<br />

バイダは、アプリケーションで -Bprotected を有効にする方法について、David Gross 著『Library Providers’ Guide to Symbol Binding』を参照してください。<br />

アプリケーションのビルド時に、このオプションを-exec と併用して、最速のデータ アクセスと呼び出しシーケンスを<br />

得ることができます(-exec と-minshared を参照)。<br />

-Bprotected_data<br />

すべてのデータ シンボルを、保護エクスポート クラス有としてマークします。これは、–Bprotected で説明したデータ<br />

アクセスの最適化を意味します。このオプションは、-Bprotected で利用可能な最適化のサブセットを取得する目<br />

的で、アプリケーションが実行する共有ライブラリ呼び出し用のシステム ヘッダ ファイルが組み込まれていないときに<br />

使用できます。ただし、アプリケーションのアクセスする共有ライブラリ データを定義するヘッダ ファイルを組み込む必<br />

要があります。最速のコードを得るには、該当するヘッダ ファイルを組み込み、-Bprotected を付けてコンパイルし<br />

てください。あるいは、ヘッダ ファイルを組み込むためのソース コード修正ができない場合、最適化アクセス シーケン<br />

スを得るには、-Bprotected_def または-exec のいずれかと -Bprotected_data を使用します。<br />

-Bprotected_def<br />

ローカルに(仮にではなく)定義されたシンボルを、保護エクスポート クラス有としてマークします。これらのシンボルの<br />

みに、–Bprotected で説明した最適化が適用されます。定義されたシンボルへの逆参照はすでに最適化可能ですか<br />

ら、+O3 以上でのみ効果をもつことに注意してください。これは、共有ライブラリ呼び出しまたはデータ アクセスのた<br />

めのシステム ヘッダ ファイルが組み込まれていないときに使用可能です。最速のコードを得るには、該当するヘッダ<br />

ファイルを組み込み、-Bprotected を付けてコンパイルします。<br />

このオプションは、-exec のサブセットです。<br />

-Bhidden[=symbol[,symbol]*]<br />

-Bhidden:filename<br />

名前の指定されたシンボルを、隠し(hidden)エクスポート クラス有として指定します。-Bhidden にシンボルが指定<br />

されていない場合は、参照されるが、変換ユニット内に定義されていないものを含めて、すべてのシンボルが、隠しエ<br />

クスポート クラス有として指定されます。隠しエクスポート クラスは、シンボルがロード モジュール外にエクスポートさ<br />

10


れないことを意味します。+Oprocelim が指定されているとき、実行ファイルでは、参照されない隠しシンボルは削<br />

除されます。<br />

コンパイラによる取り扱いは、それ以外の点では、–Bhidden を使用してシンボル リストを指定していないときの暗<br />

黙の-Wl,-a,archive_shared の指定を含めて、-Bprotected と同じです。<br />

-Bdefault=symbol[,symbol]*<br />

-Bdefault:filename<br />

指定されたシンボルを、デフォルト エクスポート クラス有として指定します。これは、シンボルがロード モジュール内<br />

部および外部にエクスポートされる可能性があることを意味します。仮シンボルについては、コンパイラは、アクセス<br />

用にリンケージ テーブルを使用します。変換ユニットに対してローカルでない関数呼び出しについては、コンパイラは、<br />

呼び出し前後の GP を保存、復元します。ただし、ローカルに(仮にではなく)定義されたシンボルへのアクセスは、–<br />

Bprotected で説明したように最適化されます。デフォルトでは、すべてのシンボルがデフォルト エクスポート クラ<br />

ス有ですが、このオプションを使用して、特定シンボルについてグローバルの -Bprotected、-Bhidden または -<br />

Bextern オプションを上書きできます。たとえば、変換ユニット内のほとんどの呼び出しがロード モジュール内で解<br />

決される場合、-Bprotected の後に、-Bdefault と変換ユニット内でアクセスされる共有ライブラリ シンボルの<br />

リストを付けて指定できます。<br />

-Bextern[=symbol[,symbol]*]<br />

-Bextern:filename<br />

機能としては、-Bdefault と似ていますが、このオプションは、シンボルが別のロード モジュールにある可能性が高<br />

いこと、したがって、コンパイラ側でこれらのシンボルへの呼び出しについてインポート スタブをインライン化するのが<br />

望ましいことを伝える、追加のヒントをコンパイラに提供します。ローカル定義シンボルを -Bextern オプションで指<br />

定すると、コンパイラは、そのシンボルをデフォルト エクスポート クラスとしてマークします。また、-Bdefault と異な<br />

り、そのローカル定義シンボルについてコンパイル時バインディングも回避されます。これは、シンボルへの参照がリ<br />

ンケージ テーブルを経由すること、そのシンボル呼び出し前後の gp が保存、復元されることを意味します。さらに、-<br />

Bextern で指定した他のシンボル同様に、ローカル定義シンボルの呼び出しは、インライン化したインポート スタブ<br />

を経由して実行されます。これらのすべての結果として、そうしたシンボルにアクセスするときに、パフォーマンスのペ<br />

ナルティが生じるのは明らかです。したがって、–Bextern を使用するのは、外部または代替可能であることが予測<br />

されるシンボルのみにしてください。<br />

シンボル リストなしで指定すると、-Bextern は、未定義および仮定義シンボルにのみ適用されます。<br />

-exec<br />

コードを実行可能プログラム用にコンパイルすることを宣言します。-Bprotected_def と同様に、すべてのローカ<br />

ル定義シンボルが、保護エクスポート クラス有としてマークされます。また、実行可能プログラムで定義されることが<br />

分かっているシンボルへのアクセスには、リンケージ テーブル経由アクセスではなく、絶対アドレスを使用します。<br />

-minshared<br />

-Bprotected -exec と等値です。共有ライブラリの使用を最小限にする実行プログラムをビルドするときに、この<br />

オプションを使用して、非共有ライブラリ コードおよびデータへの最速アクセス シーケンスを生成します。<br />

その他の最適化機能の制御<br />

+Odata_prefetch=[none|direct|indirect] (デフォルト +Odata_prefetch=indirect)<br />

+O[no]data_prefetch (+Odata_prefetch = +Odata_prefetch=indirect)<br />

データ プリフェッチの挿入を有効にします。現在、データ プリフェッチが挿入されるのは、配列アクセス用ループ内の<br />

みです。+Odata_prefetch=direct を使用すると、誘導アドレスに対するロード、ストア命令用にプリフェッチが<br />

挿入されます。このプリフェッチは、メインメモリへの遅延がカバーされる(たとえば、データがどのキャッシュ内にもな<br />

いことを想定する)ように挿入されます。またこのプリフェッチには、アクセス先のデータ型について適切なキャッシュ<br />

ヒントが付加されます。プリフェッチは、ループを使用した実行度の高いパス上にある、整数と浮動小数のロード、およ<br />

び浮動小数のストアに挿入されます。コンパイラは、いくつかの手法を使用して、プリフェッチのオーバヘッドを最小に<br />

しようと試みます。これには、ループのアンローリングが含まれることもあります。デフォルトの +Odata_prefetch<br />

または +Odata_prefetch=indirect、さらに、+Odata_prefetch=direct で挿入されるプリフェッチに加え<br />

て、コンパイラは、ループ内の誘導式に間接的に依存するアドレスを使用してアクセスされるデータについてもプリフェ<br />

ッチを挿入します。つまり、データ アドレスを作成するために、他の中間計算を利用した誘導式が提供されます。現在、<br />

サポートされている中間計算のタイプは、ロードとビット抽出です。たとえば、次のコードで、配列 A は、配列 B からロ<br />

ードされたインデックスを使用して間接アクセスされます。<br />

for(i=0;i


ead A[B[i]]<br />

直接プリフェッチ アルゴリズムであれば、誘導アドレスをもつ配列 B についてプリフェッチを挿入します。間接プリフェ<br />

ッチでは、コンパイラは、配列 A が B[i]で間接的にアクセスされることを検出し、それに応じてプリフェッチを挿入し<br />

ます。コンパイラは、A のプリフェッチ アドレスを計算するため、配列 B を投機的にロードします。プリフェッチ ディスタ<br />

ンスが PF のとき、間接プリフェッチは、次のコードを上記ループに挿入します。<br />

lfetch B[i+PF*2]<br />

index=ld.s B[i+PF]<br />

lfetch A[index]<br />

配列 B を通常のプリフェッチ ディスタンスの 2 倍でプリフェッチしていることに注目してください。これは、配列 A を通<br />

常のプリフェッチ ディスタンスでプリフェッチするためには、配列 B を通常の 2 倍のプリフェッチ ディスタンスで投機的<br />

にロードする必要があるためです。配列 B の終端を越えることがあるため投機的ロードを使用します。これにより、A<br />

のプリフェッチアドレスに対するロードで例外は発生しません。<br />

詳しくは、『Itanium Architecture Software Developers Manual, volumes 1-3』を参照してください<br />

( http://h21007.www2.hp.com/dspp/topic/topic_DetailSubHeadPage_IDX/1,4946,0-10402-TECHDOCUMENT-40106,00.html<br />

(英語) )。<br />

+O[no]inline:filename<br />

+O[no]inline=symlist<br />

#pragma no_inline<br />

#pragma inline<br />

#pragma [no]inline_call<br />

特定の関数用にインライン化を有効または無効にします。関数は、別のファイル filename 内、またはコマンド行の<br />

symlist 内のいずれかに指定できます。デフォルトでは、コンパイラは、経験則を使用して、インライン化候補の損<br />

益を判定しますが、このオプションは、その経験則を上書きします。特定関数のインライン化が常に有益であるか、ま<br />

ったく有益でないかを分かっているときに、このオプションを使用できます。また、決してインライン化すべきでない関<br />

数を指定するのに no_inline プラグマ、常にインライン化すべき関数を指定するのに inline プラグマも使用でき<br />

ます。該当するプラグマを、インライン化するまたはインライン化しない関数の定義を含むソース ファイル内に配置し<br />

てください。[no]inline_call プラグマは、特定呼び出しサイトのインライン化を有効、無効にするときに使用しま<br />

す。引数はなく、次のステートメント中の最も外側、最左端の呼び出しに影響します。ただし、最初のリリースには<br />

[no]inline_call プラグマは実装されていません。<br />

+O[no]procelim (デフォルト +Oprocelim)<br />

呼び出しされないプロシージャの削除を有効または無効にします。参照されない非隠し、非静的シンボルに加えて、<br />

隠しエクスポート クラスとしてマークされたプロシージャが削除されます。このオプションは、実行可能プログラムのサ<br />

イズを削減し、これにより、TLB と命令キャッシュ動作を改善できます。サポートされるのは、実行可能プログラムにつ<br />

いてのみです。<br />

+Otype_safety=[off|limited|ansi|strong]<br />

(デフォルト +Otype_safety=off, limited になることもあります)<br />

+Optrs_strongly_typed(+Otype_safety=strong と同じ)<br />

+Optrs_ansi(+Otype_safety=ansi と同じ)<br />

上記オプションがサポートされるのは、C アプリケーションのみです。上記オプションは、コード最適化時にコンパイラ<br />

がどのタイプのエイリアシング保証を想定できるかを指示するのに使用します。指定したオプションがなんらかの程度<br />

の型の安全を保証していて、それが、実際にはコードで順守されない場合、アプリケーションが正常に実行されない<br />

可能性があります。+Otype_safety=off は、最も保守的で、すべてのタイプのオブジェクトについて相互エイリア<br />

スの可能性があることを伝えます。+Otype_safety=limited は、コードが ANSI エイリアス規則に準拠している<br />

こと、指定のないオブジェクトは未知の型として取り扱われることを指示します。言い方を変えると、float 型と int<br />

型のオブジェクトは、それぞれ異なるメモリ ロケーションを参照すると想定することができ、型の異なるオブジェクトへ<br />

のアクセスをお互い自由にスケジューリングできます。このオプションは、両方のアクセスが、指定のないメモリを参照<br />

できるときには、異なる型のアクセスを明確にしません。また、ANSI 規則の指定するように、文字オブジェクトは他の<br />

型のオブジェクトを参照できるため、他のオブジェクトに関して保守的に最適化しなければなりません。<br />

+Otype_safety=ansi は、コードが ANSI エイリアス規則を順守すること、指定のないオブジェクトについても、指<br />

定されたオブジェクトと同様に扱うことを指示します。最も積極的な明確化をするには、+Otype_safety=strong<br />

を使用します。このオプションは、文字型の左辺値( lvalue) を通じたアクセスは、他のタイプのオブジェクトを参照でき<br />

12


ないことを除いて、コードが ANSI エイリアス規則に準拠することを指示します。また、構造体と共用体フィールドのア<br />

ドレスは取得されないと想定されます。<br />

+O[no]ptrs_to_globals (デフォルト +Optrs_to_globals)<br />

+Optrs_to_globals を使用すると、静的に割り当てられたデータ(ファイル スコープのグローバルデータ、ファイ<br />

ル スコープの静的データ、関数スコープの静的データを含む)は、ポインタを使用して読み込み、書き込みされないと<br />

想定します。この想定の下で、ポインタの使用頻度の高いコードについて、一層積極的な最適化とスケジューリング<br />

が可能です。<br />

+Ovolatile=qualifier1[,qualifier2]*<br />

Fortran ではサポートされません<br />

volatile のすべての使用箇所に、指定した型修飾子を適用するのと同じ効果です。<br />

+O[no]cross_region_addressing(デフォルト +Onocross_region_addressing)<br />

リージョン境界をまたぐアドレッシングの使用を有効/無効にします。このオプションを有効にすると、結果として比較<br />

的保守的なアドレス計算となり、パフォーマンスが低下します。ポインタ(ポインタ配列を含む)が、そのポインタからの<br />

オフセットとしてアクセスされるデータとは異なる、別のリージョンを指す場合、有効にすることが必須です。これは、標<br />

準準拠のアプリケーションでは発生しません。これが発生するようなプログラムでは、このオプションを有効にしている<br />

場合、コンパイラは、アドレスがいつリージョン境界をまたぐかが分からないため、インクリメント後(post-incrementing)<br />

ロード/ストア命令を利用することができません。このオプションは、+DD64 ではなんの効果もありません。<br />

+[no]parmsoverlap (デフォルト +Oparmsoverlap)<br />

Fortran ではサポートされません<br />

+Onoparmsoverlap を使用すると、オプティマイザは、サブプログラムの複数の引数が参照するメモリ ロケーショ<br />

ンが重複していないことを想定します。この想定の下で、ポインタの使用頻度の高いコードについて、一層積極的な最<br />

適化とスケジューリングが可能です。<br />

+O[no]parminit (デフォルト +Onoparminit)<br />

Fortran ではサポートされません<br />

このオプションを有効にすると、オプティマイザは、呼び出し側で指定のない関数パラメータをゼロに初期化する命令<br />

を挿入します。これにより、パラメータ レジスタで NaT 値が回避されます。このオプションを有効にすると、結果として、<br />

若干のパフォーマンス低下が生じますが、正確さのために必須の場合もあります。<br />

+O[no]recovery (デフォルト +Orecovery)<br />

制御の投機的実行用にリカバリ コードを生成するかどうかを指定します。このオプションを有効にすると、コンパイラ<br />

は、各制御の投機的ロードについて、それに対応する制御投機チェック命令を生成し、ロード命令のオリジナル位置<br />

に挿入します。そのあと、リカバリ コードのブロックを、チェック命令の指定したラベル位置に挿入します。<br />

+Onorecovery を指定すると、制御投機チェック命令またはリカバリ ブロックは挿入されません。代わりに、ELF ファイ<br />

ルで SHF_IA_64_NORECOV フラグがセットされ、オペレーティング システムは、例外検出時にただちにリカバリを処<br />

理します。+Onorecovery の利点は、チェック命令がないためにクリティカル パスが短く、かつ全体的にもリカバリ ブ<br />

ロックがないため、コード サイズが小さくなることです。短所として、そのアプリケーションでデータ TLB ミスが多くなる<br />

可能性があります。これは、投機的ロード実行時に TLB ミスが起きるためで、チェック命令実行時よりも、格段に多くの<br />

回数の TLB ミスが起きる可能性もあります(例えば決して真にならない if 文の中からその上方に移動させた投機ロー<br />

ド)。もっとも、多数の投機的ロードで TLB ミスまたはその他の例外を受け取らない限り、コード サイズが減少すること<br />

で、多くの場合、実質的な改善が得られます。+Onorecovery オプションは、一般に安全です。ただし、メモリ アクセス<br />

例外に依存するシグナルハンドラを使用するアプリケーションでは不正確な動作をする可能性はあります。また、不<br />

正確なアプリケーションが、+Onorecovery により、別の不正確な動作を引き起こす可能性もあります。<br />

+O[no]store_ordering (デフォルト +Onostore_ordering)<br />

Fortran ではサポートされません。<br />

このオプションを有効にすると、オプティマイザは、別のスレッドからも見える可能性のあるメモリへのストアについて、<br />

元のプログラム順序を維持するように強制します。これは、強い順序付け(strong ordering)を意味するものではあり<br />

ません。このオプションを使用することで、+Ovolatile により提供される、グローバル変数へのすべてのアクセスに適<br />

用する、より保守的なボラタイル セマンティクス(volatile semantics)を使用せずに、ストアのプログラム順序付けを達<br />

成できます。<br />

#pragma IF_CONVERT<br />

ブロック スコープのこのプラグマを使用して、if 変換により、スコープ内で条件コードから生成するすべての制御フロ<br />

ーを削除するように、コンパイラに指示できます。if 変換のプロセスにより、コンパイラは、プレディケートを使用して、<br />

条件分岐を削除します。+O2 以上では、デフォルトで、コンパイラは、経験則を使用して、if 変換を適用して条件分岐<br />

13


を削除することが有益かどうかを判定します。このプラグマは、その経験則を上書きして、プラグマのスコープ内です<br />

べての非ループ制御フローを削除するようにコンパイラに指示します。制御フローのないループだけがコンパイラにソ<br />

フトウェア パイプライン化されるため、このプラグマを使用することで、条件コードを含む内部ループのソフトウェア パ<br />

イプライン化が円滑になります。このプラグマが内部ループのスコープ内に配置されているとき、コンパイラは、ループ<br />

バック分岐を除くすべての分岐を削除します。<br />

#pragma UNROLL_FACTOR n<br />

ブロックスコープのこのプラグマは、最も内側のループを n 回アンロールするように指示します。デフォルトで、コンパ<br />

イラは、経験則を使用して、内部ループに対する最適のアンロール基準を判定します。しかし、そのループについて特<br />

定のアンロール基準が最適であること、または、ループにアンロールを適用しないのが最善であることが分かってい<br />

る場合には、UNROLL_FACTOR プラグマを使用して、この情報をコンパイラに伝えることができます。指定したアンロ<br />

ール基準は、コンパイラの計算したアンロール基準を上書きします。n=1 を指定すると、コンパイラはループをアンロ<br />

ールしません。n=0 を指定すると、コンパイラは、自身の経験則を使用して、最適のアンロール基準を判定します(プ<br />

ラグマを指定しないのと効果は同じです)。最も内側のループ内に配置されているプラグマだけが処理されます(他の<br />

ループ内のプラグマは無視されます)。<br />

14


プロファイル ベースの最適化<br />

プロファイル ベースの最適化 (PBO) は、アプリケーション用に収集された実行プロファイルを使用してパフォーマンスを<br />

改善する、コード変換のセットです。この最適化の実行には 3 つのステップがあります。<br />

1. 計測用実行ファイルの作成 ⎯ プログラムを再コンパイルして、実行プロファイル収集用にプログラムを準備します。<br />

2. データ収集 ⎯ 代表的データを使用してプログラムを実行し、実行プロファイル統計情報を収集します。<br />

3. 最適化 ⎯ プロファイル データに基づいて最適化コードを生成します。<br />

下記のように、<strong>HP</strong> コンパイラでは、+Oprofile=collect と +Oprofile=use コマンド行オプションを使用して、プロ<br />

ファイル ベースの最適化を実行します。<br />

計測用実行ファイルの作成<br />

プログラムを計測用にコンパイルするには、次のように +Oprofile=collect オプションを使用します。<br />

cc –Aa +Oprofile=collect –cs ample.c 計測用にコンパイル<br />

cc –o sample.exe +Oprofile=collects ample.o リンクして計測用実行プログラムを作成<br />

最初のコマンド行は、コードをコンパイルします。+Oprofile=collect オプションは、プロファイル収集用モジュール<br />

を作成するようコンパイラに要求します。最初のコマンド行の -c オプションは、リンクを実行せず、sample.o と呼ばれ<br />

る中間オブジェクトを作成します。2 つ目のコマンド行は、-o オプションを使用して、sample.o を sample.exe にリン<br />

クします。+Oprofile=collect オプションは、データ収集コードを使用して sample.exe を作成します。<br />

注記: 計測用プログラムは、非計測用プログラムよりも実行速度が低下します。計測用プログラムの使用は、プロファ<br />

イル ベースの最適化用に統計情報を収集する場合に限定してください。<br />

プロファイル用データの収集<br />

アプリケーション用に実行プロファイルを収集するため、次のように、代表的データを使用して、仲介プログラムを実行し<br />

ます。<br />

sample.exe < input.file1 実行プロファイル データを収集します。<br />

sample.exe < input.file2<br />

このステップでは、プロファイル統計情報を作成し、ファイル(デフォルトで flow.data)に書き込みます。異なる計測用<br />

プログラムの複数回のテスト実行から収集される統計情報を、この1つのデータ収集ファイルに蓄積できます。<br />

プロファイル ベースの最適化の実行<br />

収集済みの実行時プロファイル統計情報に基いてプログラムを最適化するには、次のようにプログラムを再コンパイル<br />

します。<br />

cc –Aa +Oprofile=use –O –cs ample.c 最適化用にコンパイル<br />

cc –o sample.exe +Oprofile=use –O sample.o 最適化用にリンク<br />

+Oprofile=useoption は、レベル 2(-O または +O2)以上でサポートされます。<br />

プロファイル データ ファイルの保守<br />

プロファイル ベースの最適化により、実行プロファイル データがディスク上のファイルに書き込まれます。デフォルトの<br />

書き込み先ファイル名は flow.data で、現在の作業ディレクトリに保存されます。このプロファイル データ ファイルの<br />

デフォルト名は、変更可能です。このファイル名の変更は、大きなプログラム、または多数の異なるプログラム ファイル<br />

を含むプロジェクトで有益です。デフォルト以外のプロファイル データ ファイル X を選択するには、+Oprofile=use:X<br />

コマンド行オプションを使用します。FLOW_DATA 環境変数を使用して、+Oprofile=use を指定したコンパイル時の、<br />

プロファイル データ ファイル名を指定することもできます。[:file] 修飾子は、FLOW_DATA 環境変数に優先します。<br />

次の例では、FLOW_DATA 環境変数で flow.data 以外のファイル名を設定しています。プロファイル データは、<br />

flow.data ではなく、/users/profiles/prog.data に書き込まれることになります。<br />

%setenv FLOW_DATA /users/profiles/prog.data<br />

%cc –Aa –c +Oprofile=collect sample.c<br />

%cc –o sample.exe +Oprofile=collect sample.o<br />

15


%sample.exe < input.file1<br />

%cc –o sample.exe +Oprofile=use +03 sample.o<br />

次の例で、+Oprofile=use:オプションは、/users/profiles/prog.data を使用して、flow.data ファイル名<br />

を上書きします。<br />

%cc –Aa –c +Oprofile=collect sample.c<br />

%cc –o sample.exe +Oprofile=collect sample.o<br />

%sample.exe < input.file1<br />

%mv flow.data /users/profile/prog.data<br />

%cc –o sample.exe +Oprofile=use:/users/profiles/prog.data +03 sample.o<br />

注記: プロファイル ベースの最適化は、各ハイレベルの最適化で、アプリケーションのパフォーマンスに大きな影響を<br />

及ぼします。プロファイル ベースの最適化を有効にするのは、アプリケーション開発の最終段階にしてください。最高の<br />

パフォーマンスを得るため、ソース コード変更後にアプリケーションを再プロファイリングし、再度最適化してください。<br />

ItaniumとPA-RISCのプロファイル ベース最適化の相違<br />

ユーザー モデルは同じですが、Itanium コンパイラでのプロファイル べース最適化の基盤実装と PA-RISC コンパイラで<br />

のそれとは相当の違いがあります。PA-RISC から Itanium へ移行するときは、次の点に留意してください。<br />

• Itanium コンパイラの+Oprofile=collect オプションと PA-RISC コンパイラの +I オプションと等価であり、Itanium<br />

コンパイラの+Oprofile=use と PA-RISC コンパイラの +P オプションは等価です。ただし、Itanium コンパイラでは<br />

PA-RISC オプションも有効です。<br />

• PA-RISC 実装では、-c +I または -c +P を付けてモジュールをコンパイルすると、ISOM (ハイレベル中間) オブジ<br />

ェクト ファイルが生成されます。実際のコード生成は、最終リンク段階まで延期されます。Itanium ベースの実装では、<br />

これと異なり、(+I または +P いずれかを指定しても)-c コンパイル時にコードが生成されます。<br />

• PA-RISC は、–O 最適化と組み合わせたプロファイル収集 (+I) をサポートしています。現在、Itanium ベースのコンパ<br />

イラでは、プロファイル収集は、デフォルトの (+O1) 最適化との組み合わせでのみサポートされています。-O(または<br />

+O3/+O4)との組み合わせで +I を使用すると、コンパイルは、警告を発して、+I コンパイルの最適化レベルを +O1<br />

に引き下げます(+P コンパイルでは最適化レベルを引き下げません)。<br />

• PA-RISC +I 実装では、プロファイル カウンタのサイズは 32 ビットです。計測用実行可能プログラムの実行用に入力<br />

データ セットを選択する場合、データ収集のための実行が長すぎると、カウンタ飽和が発生する可能性があります。<br />

Itanium では、プロファイル カウンタのサイズは 64 ビットです。したがって、カウンタ飽和を心配せずに、かなり長めに<br />

データ収集のための実行を実施できます。<br />

16


お問い合わせはカスタマー インフォメーションセンターへ<br />

03-6416-6660 月~金9:00~19:00 土10:00~18:00(日、祝祭日、年末年始および5/1を除く)<br />

<strong>HP</strong>-UX製品に関する情報は http://www.hp.com/jp/hpux<br />

Intel、インテル、Intel Inside ロゴ、Itaniumは、米国におけるIntel Corporationまたは<br />

その子会社の商標または登録商標です。<br />

UNIXは、The Open Groupの登録商標です。<br />

記載されている会社名および商品名は、各社の商標または登録商標です。<br />

記載事項は2004年1月現在のものです。<br />

本書に記載された内容は、予告なく変更されることがあります。<br />

本書中の技術的あるいは校正上の誤り、省略に対して、<br />

いかなる責任も負いかねますのでご了承ください。<br />

© Copyright 2004 Hewlett-Packard Development Company,L.P.<br />

日本<strong>ヒューレット・パッカード</strong>株式会社<br />

〒140-8641 東京都品川区東品川2-2-24 天王洲セントラルタワー<br />

PDFHS04013-01

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!