...

コンパイラ テクノロジの概要

by user

on
Category: Documents
12

views

Report

Comments

Transcript

コンパイラ テクノロジの概要
コンパイラ テクノロジの概要
HP および Intel® Itanium® プロセッサ ファミリ
White Paper
目次
Itanium ベース HP-UX システム用 HP コンパイラ .............................................................................................3
HP コンパイラについて ................................................................................................................................3
Itaniumベース システムの最適化 ..................................................................................................................3
プレディケーション...................................................................................................................................4
制御の投機的実行 .................................................................................................................................................................................................4
データの投機的実行..............................................................................................................................................................................................5
明示的並列化 ...........................................................................................................................................................................................................6
AR1204 コンパイラの新機能 .......................................................................................................................6
パフォーマンス ..........................................................................................................................................................................................................6
HPコンパイラの主要な機能 ..........................................................................................................................6
標準準拠...............................................................................................................................................6
互換性..................................................................................................................................................7
広範なアプリケーションへの利用 ...............................................................................................................7
高速な開発とデバック..............................................................................................................................7
高度なローレベルの最適化 ......................................................................................................................8
プロファイル ベースの最適化....................................................................................................................8
強力なハイレベルの最適化 ......................................................................................................................9
精密な浮動小数点制御 .........................................................................................................................12
広範なインライン アセンブリ ...................................................................................................................13
Itaniumベース アプリケーションのチューニング ..............................................................................................14
プロファイリング....................................................................................................................................14
ヘッダー ファイルのインクルード..............................................................................................................14
プロセッサのスケジューリング .................................................................................................................14
リンク モードの選択...............................................................................................................................15
ページ サイズの拡大.............................................................................................................................15
回復コードの削除 .................................................................................................................................15
アプリケーション特性の記述 ...................................................................................................................16
プロファイル ベースの最適化によるチューニング .......................................................................................16
浮動小数点数値コードのチューニング ......................................................................................................17
プログラム モジュール間のチューニング ...................................................................................................18
1
柔軟な最適化の実行.............................................................................................................................18
インライン アセンブリの使用 ...................................................................................................................18
最適化に関する問題のトラブルシューティング ...........................................................................................19
参考文献 ................................................................................................................................................21
付録:非互換性のまとめ ............................................................................................................................22
旧形式 C++ ランタイムと標準 C++ ランタイム ..........................................................................................22
HP-UX Release B.11.22 での C コンパイラの変更点..................................................................................22
HP-UX Release B.11.22 で修正された C++ の問題点................................................................................22
2
Itanium ベース HP-UX システム用 HP コンパイラ
本書では、インテル Itanium® ベース HP-UX システム用 HP コンパイラの主要機能の技術概要を説明します。
HP コンパイラについて
HP とインテルにより共同開発されたインテル® Itanium® アーキテクチャには、EPIC (Explicitly Parallel Instruction
Computing: 明示的並列命令コンピューティング) が採用されています。EPIC を採用することで、プロセッサは高度なコ
ンパイラ テクニックと大量のプロセッサ リソースを利用でき、従来の RISC プロセッサに比べ、複数の命令を同時により
高速に実行できるようになります。HP コンパイラは、このアーキテクチャを実際のアプリケーションに活用できるように、
アーキテクチャと並行して設計されました。本書では、HP コンパイラの主要機能を示し、さらに HP コンパイラを使用して、
開発者がどうしたら Itanium ベースシステムの優れた性能を引き出すことができるかを示します。
HP は、C、C++、および Fortran 言語に対応した、Itanium ベース システム用のコンパイラ ファミリを提供します。HP の
各コンパイラは総合的な設計構造を共有することで、コード ジェネレータ、オプティマイザ、リンカ、デバッガのような共通
の機能要素を簡単に統合できます。
HP コンパイラ構造は、入力ソース コードの語彙、構文、セマンティック分析のための要素を含む、言語依存のフロント
エンドから始まります。各フロント エンドはプログラムの中間レベル コードを作成します。ハイレベル オプティマイザは、
中間コードの性能を強化するために最適化を行います。コード ジェネレータは、中間表現を対象システムにほぼ対応す
る命令列に変換します。最後に、ローレベル オプティマイザが機械語コードを生成し、性能を改善するために追加変換
を行います。
HP は、Itanium ベース HP-UX 開発専用のコンパイラを提供します。HP のコンピューティング ソリューション プロバイダ
プログラムのメンバーである独立系ソフトウェア ベンダーのために、HP は Itanium ベース システムのコードを生成する
HP PA-RISC HP-UX システム用のクロス開発コンパイラを用意しています。クロス開発コンパイラが既存の HP PA-RISC
開発環境を乱すことがないため、完全な Itanium ベース開発インフラへの段階的な移行が可能になります。
Itanium ベース システム上の HP-UX システム ライブラリは、通常、HP PA-RISC 上の対応するライブラリのスーパー セ
ットになります。たとえば、Itanium ベース システムの HP-UX C/C++ 数学ライブラリは、PA-RISC ライブラリの主要スー
パー セットである API を提供します。これには、4 種類の浮動小数点型に対応する、C99、Unix 95、および PA-RISC
数学関数のすべてが含まれています。Itanium ベース システムに提供される関数は、PA-RISC の関数に比べ、一般に
より高速で正確であり、例外事例の処理にもより優れた一貫性を示します(20 ページの「参考文献」の項目 1 を参照)。
数学
ライブラリ
ハイレベル
オプティマイザ
コード
ジェネレータ
ローレベル
オプティマイザ
リンカ
プロファイル
データ
ソース
コード
ハイレベル
中間コード
デバッガ
ロード
モジュール
パフォーマンス
分析ツール
ローレベル
中間コード
再配置可能
オブジェクト コード
実行可能
コード
図 1. HP コンパイラの内部構造
すべての HP コンパイラは、言語間の相互運用性を最大にするために、コード ジェネレータとオプティマイザの共通の実
装を共有します。
Itanium ベース システム用の HP コンパイラは、HP-UX 11i 自体を含む、HP-UX 11i 対応の膨大な行数の C、C++、お
よび Fortran ソース コードをすでにコンパイルしてきました。このようなコンパイルの多くは、ハイレベルの最適化が行わ
れます。100 社を超える独立系ソフトウェア ベンダーが、自社アプリケーションを HP-UX 11i 上で使用できるようにする
ために、HP のコンパイラを使用しています。HP は HP のコンパイラを使用し、詳細な最適化を行って、SPEC2000 ベン
チマークのパフォーマンスを調整してきました。このベンチマークは、合計 30 のアプリケーションを含んでいます。これ
らのプログラムは、プレディケーション (predication)、投機的実行 (speculation)、データ プリフェッチなど、高度な
Itanium プロセッサ ファミリの機能を幅広く利用しています。
Itanium ベース システムの最適化
インテル Itanium アーキテクチャは、命令レベルの並列化 (複数命令の同時実行) を最大化することで、実行時間の短
縮を追求しています。Itanium アーキテクチャでは、コンパイラで命令レベルの並列性 (instruction-level parallelism: ILP)
を最大化するための 3 つの主要な機能が用意されています。
3
• プレディケーション
• 制御の投機的実行およびデータの投機的実行
• 明示的並列化
これらの機能をアーキテクチャからサポートすることは重要ですが、優れたアプリケーション パフォーマンスを実現する
ために、コンパイラもこれらの機能を最大限に活用する必要があります。HP のコンパイラは、アーキテクチャの持つこれ
らの機能を最大限に活用するために、アーキテクチャと並行して設計、構築されました。
プレディケーション
プレディケーションとは、プレディケート (述語) レジスタに含まれるブール値の設定に基づいて、命令を条件付きで実行
することです。インテル Itanium アーキテクチャには 64 のプレディケート レジスタがあり、ほぼすべての命令に対する
実行の制御に使用されています。
以下の例では、 x に対する代入の両方が同じサイクルで実行され (2 つのプレディケーションが同時に真になることは
あり得ないため)、2 つの命令と最低 1 つの実行サイクルを節約し、分岐での予測ミスのリスクを防止できます。
例 1: プレディケーションの使用
if (a == 0) {
x = 5;
} else {
x = *p;
}
コンパイラはプレディケーションを使用して、分岐命令上の制御依存を、比較命令上のデータ依存に変更できます。
例 2:分岐を使用して生成された例 1 のコード
(p1)
L1:
L2:
cmp.ne.unc p1,p0 = a,0
br L1 ;;
mov x = 5
br L2 ;;
ld x = [p]
実行される x への代入は、最初の分岐命令中のプレディケート (p1) に制御依存しています。
制御依存からデータ依存への変換には、以下の 2 つの利点があります。
• 分岐の削除。各サイクルに実行される命令の数が増えます。たとえば、例 2 の分岐が削除されると、x に対する 2
つの代入操作を同じサイクルで実行できます。
• 分岐に関連する予測ミスのペナルティの除去。パイプライン プロセッサでは、分岐の存在は、パイプライン フロー
に崩壊が起こる可能性を示します。プロセッサは条件付きの分岐が行われるかどうかと、分岐が間接的な場合の
分岐先を予測しなければなりません。誤った予測は、パイプラインをフラッシュし、再始動させます。パイプラインが
深く、1 サイクルの帯域幅が広い場合、パフォーマンスは著しく悪化します。インテル Itanium プロセッサでは、たと
えば、分岐での予測ミスによるペナルティは 9 サイクルで、これは 54 の命令発行の機会を失うことを表していま
す。高度な分岐予測技術を使用しても、わずかな確率で起こる分岐予測のミスは、パフォーマンスのかなりの損失
となります。
例 3:データ プレディケーションを使用して生成された例 1 のコード
(p2)
(p1)
cmp.ne.unc p1,p2 = a,0 ;;
mov x = 5
ld x = [p]
例 3 では、すべての分岐が除去され、x への代入は、実行するプレディケートを定義する比較にデータ依存しています。
制御の投機的実行
制御の投機的実行とは、ある命令について、その実行を制御しているすべての条件を実行する前にその命令を実行す
ることです。制御の投機的実行の使用により、コンパイラは、プログラムが保護条件の評価結果を待つのではなく、保護
条件と同時または保護条件よりも先に条件付きコードを実行するようなコードを生成できます。このような同時性により、
実行時のパフォーマンスが飛躍的に向上します。
例 4:制御の投機的実行コード
int a,b;
4
extern int *p;
extern int global;
if (condition) {
a = global;
b = *p + 2;
}
制御の投機的実行を使用すると、HP コンパイラは、条件 (condition) よりも先に then 句にある 2 つの代入文をプ
ログラムが実行できるコードとして生成できます。
整数変数のロードおよび算術演算は、予想外の副作用が発生しないため、制御の投機的実行の理想的な候補といえま
す。ソース コード文は、ロード、算術演算、およびストアを利用します。ソース コード文が条件の評価により保護されてい
る場合、ロードおよび算術演算は投機的に実行されますが、ストア操作は条件の評価に依存するため、投機的には実
行されません。呼び出しについても制御の投機的実行は行われません。
投機的に実行されるロードは、保護条件より先に実行されるため、(多くの理由により) 正常にロードされない場合があり
ます。Itanium ベース システムでは、投機的に実行されたロードが成功しなかった場合、ターゲット レジスタ内に投機的
実行トークン (通称 NaT) を設定します。この NaT トークンが後続の命令を通じて伝達されていきます。保護条件が最
終的に評価された後、投機的に実行された命令の結果が必要に応じて使用されます。NaT トークンが見つかった場合、
回復コード シーケンスが実行され、必要な結果が再計算されます。
例 5:制御の投機的実行を使用した例 4 のコード
(p1)
L1:
...
L2:
ld.s t1 = [p] ;;
add b = t1,2
cmp.ne.unc p1,p0 = condition,0 ;;
chk.s b, L2
ld t1 = [p] ;;
add b = t1,2
br L1
chk.s 命令は、結果レジスタ b に NaT ビットがセットされているとき、L2 にある回復コードに分岐します。回復コードは
投機的実行を行わずに b を計算します。(p1) は、プレディケートです。
さまざまな要因により、NaT トークンを設定し、回復コードを実行する、投機的なロードが生成されます。無効なアドレス
からのロードは、従来のアーキテクチャ上では通常例外を生成しますが、無効なアドレスからの投機的なロードは NaT
を生成します。また、制御の投機的実行によるロードでの TLB (translation-lookaside buffer:変換索引バッファ) ミスでも、
回復コードが存在すれば、通常は NaT を設定します。TLB とは、仮想メモリ アドレスから物理メモリ アドレス、および物
理メモリ アドレスから仮想メモリ アドレスへの変換用キャッシュです。
データの投機的実行
データの投機的実行には、以下のような、1 つまたは複数のストア命令より先にロードを実行することが含まれます。
• 元のプログラム順序のロードよりも前にあったストア命令
• ロードにより読み込まれた位置と同じメモリ位置に書き込む可能性があるストア命令
データの投機的実行では、命令レベルの並列性が向上するため、必要なサイクル数を全体的に削減できます。
例 6:データの投機的実行の使用
int a,b
extern int *p;
extern int *q;
*p = a;
b = *q + 2;
*p と *q が同じメモリ位置に存在する可能性もありますが、データの投機的実行の使用により、*q のロードを実行して
いる最後の文が *p のストアの前に移動します。
インテル Itanium アーキテクチャでは、動的にアドレス衝突を識別する機能、実行時にアドレス衝突が発見された場合
に回復コード シーケンスの実行をコンパイラが開始できる機能の 2 つの機能を提供することで、コンパイラがこの種の
投機的実行を安全に利用できるようにしています。コンパイラは、事前のロードによりアクセスされたアドレスへの書き込
みの有無をチェックする、先行チェック (chk.a) 命令を利用します。このような衝突が発生した場合、先行チェックはコン
パイラが生成した回復コードに分岐し、そこでロードを再実行して正しい値を確保します。
例 7:データの投機的実行を使用した例 6 の生成コード
5
L1:
...
L2:
ld.a
add
st
chk.a
t1 = [q] ;;
b = t1,2
[p] = a
[p] = a
ld
add
br
t1 = [q] ;;
b = t1,2
L1
*q のロードが *p のストアより前に移動しています。chk.a では b に含まれる書き込みの衝突をチェックして、L2 へ
の分岐後にこれらの値を訂正します。
明示的並列化
明示的並列化を使用すると、コンパイラがそのプログラムの内容を理解し、プロセッサ リソースのモデルとの組み合わ
せで、並列して実行できる命令グループを生成できます (ハードウェア依存に関する解析を行う必要なしに)。現在の
Itanium プロセッサは各サイクルで最大 6 つの命令を実行できます (3 つの命令そけぞれが 2 バンドル)。コンパイラは、
大きなレジスタ ファイルと複数の実行ユニットをサポートしているため、複数の演算を並列して実行するようにスケジュ
ールできます。命令ストリームの明示的な「ストップ ビット」を使用して、、コンパイラは、どのグループの命令を同じサイ
クルで実行できるか正確に示します。また、コンパイラは、プレディケーション、投機的実行、ループのモジュロ スケジュ
ーリングの技術を使用して並列化の機会を増やし、各サイクルで実行する並列演算の数を最大化して、コードを最適化
します。
AR1204 コンパイラの新機能
HP コンパイラの AR1204 (A.06.00) リリースは、以下をはじめとする多数の新しい機能を実現しています。
• 最新の ISO C++ と ISO C99 言語標準に厳密に準拠することで、C++ テンプレートのサポートが飛躍的に改善
• C および C++ の両方に対する有用な警告診断
• Tru64 開発者とアプリケーションの HP-UX への移行を容易にする Tru64 C++ コンパイラとのルックアンドフィール
の集約
パフォーマンス
上記の新機能に加え、AR1204 リリースは、アプリケーション パフォーマンスの飛躍的な向上を提供します。AR0304
リリースと比較すると、SPECint-peak では 4.3% の改善、SPECint-base では 4.8% の改善、SPECfp では 1.8% の改
善が見られます。
HP コンパイラの主要な機能
以下の各セクションでは、以下の主要機能について説明します。
• 7 ページの「標準準拠」
• 7 ページの「互換性」
• 7 ページの「広範なアプリケーションへの利用」
• 7 ページの「高速な開発とデバック」
• 8 ページの「高度なローレベルの最適化」
• 8 ページの「プロファイル ベースの最適化」
• 9 ページの「強力なハイ レベルの最適化」
• 12 ページの「精密な浮動小数点制御」
• 13 ページの「広範なインライン アセンブリ」
標準準拠
各 HP コンパイラは、リンクや実行時の互換性およびソース コードの移植性を強化するために、業界および国際的な事
実上の標準に準拠しています。オープンな標準に準拠することで、アプリケーション開発者の投資を保護し、新規アプリ
ケーションを迅速に開発し、導入できるようになっています。HP C コンパイラは ISO/IEC 1990 の認定を受けています。
HP Fortran コンパイラは ISO/IEC 1539-1:1997 に準拠しています。また、HP aC++ コンパイラは主として C++ 言語
(C++ 標準ライブラリを含む) に対する ISO/IEC 14882 標準に準拠しています。
HP コンパイラのすべてのコード生成およびデータ レイアウトは、インテル Itanium アーキテクチャ対応の『Itanium
Software Conventions and Runtime Architecture Guide』(20 ページの「参考文献」の項目 10 を参照) に従っています。
6
コンパイラにより生成されるオブジェクト コードは、GNU gcc などほかの ABI 準拠のビッグ エンディアン コンパイラによ
り生成されるオブジェクト ファイルやライブラリと、リンクやランタイム時の互換性があります。さらに、HP aC++ コンパイ
ラのコード生成およびデータ レイアウトは、ほとんどインテル Itanium 対応 Common C++ ABI に準拠しているため、HP
aC++ コンパイラが生成したオブジェクト コードは、一部の例外を除いて、g++ などほかの C++ ABI 準拠のビッグエン
ディアン C++ コンパイラにより作成されたオブジェクト ファイルまたはライブラリと、リンクやランタイム時の互換性があ
ります (20 ページの「参考文献」の項目 11 を参照)。
数学ライブラリは ISO/IEC C99 標準の仕様に従っており、そこには IEC 60559 (IEEE 754) の実装に関する付属書と、
IEC 60559 互換の複素数演算に関する付属書が含まれています。コンパイラと数学ライブラリは、IEC 60559 (IEEE
754) 浮動小数点標準に準拠しています。次に示す、実数の IEC 60559 浮動小数点型 3 つを完全にサポートしてい
ます。float (32 ビット)、double (64 ビット)、および long double または quad (128 ビット PA-RISC 互換の型)
です。C および C++ コンパイラとライブラリは、インテル Itanium アーキテクチャにおいて、IEC 60559 互換で 80 ビッ
トの extended 型もサポートしています (20 ページの「参考文献」の項目 2 を参照)。
互換性
HP では、現在の HP PA-RISC ベースのコンパイラと新しい世代のコンパイラ間で、ソース コードや Makefile について
ほぼ完全な互換性を提供し、ソース コードや Makefile の Itanium ベース システムへの移行を容易にしています。PARISC コンパイラのオプションは、新しいコンパイラでもほとんど変更されていませんが、新しいコンパイラでは、Itanium
ベースのシステムに用意された新機能を使用するための新しいオプションがいくつか提供されています。標準に準拠し
たり、問題を修正するために、わずかに非互換性を導入する必要がある場合があります。既知の非互換性は、22 ペー
ジの付録にまとめています。
AR1204 コンパイラは、B.11.22 および B.11.23 システムの両方で実行できるように設計されています。新しい最適化
機能の一部は、B.11.23 実行時システムに依存することがあるため、コンパイラを B.11.22 システム上で実行する場
合、これらの最適化はデフォルトで無効になります。ただし、アプリケーションが B.11. 23 システムをターゲットにしてい
る場合、ユーザーは +DO11.23 オプションを使用してこれらの最適化を有効にできます。
また、AR1204 コンパイラは、Tru64 C および C++ コンパイラの使用頻度の高い機能に対して高い互換性を提供しま
す。具体的には、Version 5 以降のデフォルトの Tru64 C++ ダイアレクトである、Tru64 C++ ARM ダイアレクトが提供
されています。
広範なアプリケーションへの利用
HP コンパイラは、ソフトウェア開発者がアプリケーションの利用を保護および拡張するために重要なものとして、非常に
頻繁に選択するコンパイラ オプションやプラグマをサポートしています。たとえば、HP コンパイラは、広く使用されている
従来の 32 ビット データ モデルと、long やポインタが 64 ビットとなっている新しい 64 ビット データ モデルの両方を
サポートしています。従来の 32 ビット データ モデルは、64 ビット環境に合わせていない多くのレガシー アプリケーショ
ンに適合します。Itanium ベース システム向けのその他多くのコンパイラでは、アプリケーションを 64 ビット データ モデ
ルに準拠させる必要があり、通常それには、レガシー アプリケーションに 64 ビットへの移行ステップを適用する必要が
あります。
Itanium ベース システム対応のアプリケーションの寿命を延ばすために、HP コンパイラは、いくつかのコード スケジュ
ール化オプションを提供しています。これらのオプションにより、ソフトウェア プロバイダは、インテル Itanium アーキテク
チャの特定の実装、またはインテル Itanium プロセッサ ファミリの全メンバーに適合する混合モデルのどちらかをターゲ
ットにできます。
高速な開発とデバック
従来のコンパイラでは、デフォルトでは最低限の最適化しか行われず、デバッグが指定された場合は最適化が全く行わ
れませんでした。このアプローチは Itanium ベース システムには適していません。Itanium ベース システムでは、最適
化されていないプログラムの実行結果は、一般に、+01 レベルで最適化された場合の 2 ~ 3 倍、+02 レベルで最適
化された場合の 4 ~ 5 倍遅くなっています。
Itanium プロセッサ ファミリの非最適化コード シーケンスの 30 ~ 50% の命令は、no-op 命令であるため、デバッグ
ビルドにも最低限の最適化が必要になります。この比較的多数の no-op 命令は、Itanium プロセッサ ファミリの 3 つ
の命令バンドルを作成するために必要です。
HP では、デフォルトで +01 レベルの最適化を提供することで、デバッグ ビルド時のパフォーマンスを大幅に向上させま
した。+01 レベルの最適化には、共通の部分式の除去、定数伝播、ロード/ストアの除去、コピーの除去、レジスタの割
り当て、制限付き基本ブロック スケジューリングが含まれます。プログラム デバッグ時の正確性の確保が配慮されます。
つまり、ソース行に対応して、ブレークポイントが必要な場所に配置され、ブレークポイントで必要な値が変数に設定され
ていることを確認できます。
7
高度なローレベルの最適化
最適化レベル 2 (オプション +02) で、HP のローレベル オプティマイザはアーキテクチャの主要機能を最大限に利用し
ます。+01 で適用されているローカルの最適化に加えて、オプティマイザは SSA (Static Single Assignment) ベースの
グローバル値の番号付け (20 ページの「参考文献」の項目 7 を参照)、グローバルなコード移動、静的および動的な命
令数を削減するための値合同 (value congruent) 命令の除去、エイリアス化されたスカラー プロモーション (20 ページ
の「参考文献」の項目 8 を参照)、「チューンダウン (tuned-down)」 ヒューリスティックを使用するプロシージャ間の高速
なインライン化を行います。ループ オプティマイザは、データ プリフェッチ、合計の削減 (sum reduction)、スカラー置換、
強度低減 (strength reduction)、増分後の統合 (post-increment synthesis)、ループのアンロールを実行します。データ プ
リフェッチは、オプティマイザが配列参照パターンを認識できるループで、自動的に実行されます。
HP コンパイラは、アプリケーション コードを、命令スケジューリングのためのオペレーション単位を形成する領域に分割
します。命令スケジューラでは、領域をできるだけ効率化するために、制御の投機的実行、データの投機的実行、およ
びプレディケーションが使用され、命令レベルの並列性が最大化されます (20 ページの「参考文献」の項目 4 を参照)。
可能であれば、コンパイル時間に対して合理的な制約が与えられ、最も内側のループがソフトウェア パイプライン化の
対象になります。ソフトウェア パイプライナは、アーキテクチャで提供される特別な分岐や循環レジスタを利用し、コード
展開をほとんどまたは全く行わずに、制御フローや非カウント ループの存在するところにもソフトウェア パイプライン化
されたループを生成します (20 ページの「参考文献」の項目 6 を参照)。
プロファイル ベースの最適化
HP はプロファイル ベースの最適化 (PBO) の提供における先駆者です (20 ページの「参考文献」の項目 3 を参照)。
PBO データはコンパイラに、分岐およびルーチン実行頻度に関する情報を、最適化への追加ガイドとして提供します。
また、データ キャッシュ最適化のガイドとして使用される、データ アクセス アドレス ストライドをコンパイラに提供します。
また、ループの最適化のガイドとして使用される、ループ繰り返しカウントをコンパイラに提供します。アプリケーションを
それぞれの実行特性に合わせてチューニングすることで、PBO は、Itanium ベースのシステム上で +02 の最適化を
30% 上回るパフォーマンスの向上を実現します。インテル Itanium ベース システム アーキテクチャは、アプリケーショ
ンの動作に基づいて命令レベルの並列性を向上させるための数多くのメカニズムを提供しているため、インテル
Itanium ベース システム上での PBO によるパフォーマンスへの効果は、従来の RISC システムよりもさらに大きなもの
になっています。
コンパイラの最適化機能の多くは、アプリケーションの実行動作についての情報により強化されます。
• 特定の最適化変換は、コード領域で実行されます。プロファイル データは、これらの変換によりターゲット領域の選
択を支援し、高頻度の実行パス内での領域交差を最小限に抑えます。
• 投機的実行やプレディケーションを行うための領域内での命令選択は、コンパイラが相対実行頻度について正確
な情報を持っているほど効果的なものになります。
• ループの最適化やプロシージャのクローン化 (Procedure Cloning) およびインライン化などのハイレベル最適化で
は、最適化の対象となるホット ループや呼び出し部分を選択する際に、プロファイル データが非常に役立ちます。
• PBO データで、アクセスが通常のストライドであることが示されていれば、オプティマイザは、リンクリスト回帰のた
めのプリフェッチを挿入できます。
• キャッシュの最適化は、頻繁にアクセスされるデータ セグメント内の大域変数と静的変数をまとめて配置するよう
に並べ替えることで強化されます。
• 「通常 2、3 回しか繰り返さないループ」であることが、PBO データのループの繰り返し回数により示されている場
合、オプティマイザは、通常の繰り返し回数を「取り除いて」、直線的コードに変換できます。これにより、その命令
に関するスケジュールの自由度を高めることができ、命令レベルの並列性が改善されます。
PA-RISC システム上のプロセスと同様に、Itanium ベース システムでは、+Oprofile=collect ビルドとそれに続く
+Oprofile=use ビルドを通じて、2 ステップの PBO プロセスを実行できます。PA-RISC とは異なり、最初のビルド ス
テップ (+Oprofile=collect) は、プロファイル収集のバイナリをマークするだけで、実行は行いません。このステッ
プでは、バイナリにはストライド プロファイリングのロードセットと、ループ繰り返しカウント プロファイリングのループセッ
トの注釈が付きます。その後バイナリが実行されたとき、Itanium プロセッサ ファミリ システム対応の HP パフォーマンス
ツール、HP Caliper が動的に実行され、実行時にプロファイル データを収集します。このデータ ファイルは、コンパイラ
が後の +Oprofile=use ビルドで使用します。現在、大域/静的変数レイアウトの最適化には、+Oprofile=use の
ほかに +Odatalayout オプションが必要です。
HP Caliper は、Itanium ベースのアプリケーションの、汎用的なパフォーマンス解析ツールです。特別なプログラムを準
備する必要がなく、マルチスレッド/マルチプロセスのプログラムを測定できます。さらに HP Caliper は、該当するパフォ
ーマンス計測値を幅広く分類して測定、報告し、開発者に対してアプリケーション動作に関する有用なフィードバックを提
供します (20 ページの「参考文献」の項目 5 を参照)。
HP コンパイラは、Itanium ベース システム用として新たに、コンパイラ オプションとソース コード プラグマを使用した、
プロファイル ベースの最適化も提供しています。これらのオプションやプラグマは、代表的なアプリケーション入力の収
8
集が困難な場面で、プロファイル データのきめ細かい調整や、プロファイル データの代替を行います。入力データが困
難な場合とは、次の理由によるものです。
• 代表的な入力データ セットが利用できるようになっていない。
• さまざまな使い方に基づくプロファイルを代表するアプリケーション構成またはシステム構成を複製するのは現実
的でない。
+Ofrequently_called オプションは、比較的高い頻度で呼び出される関数をコンパイラに示します。このオプション
では、リストまたはファイル名を引き数として使用します。引き数にファイル名を指定する場合、そのファイルにはスペー
スで区切られた関数名のリストが格納されていなければなりません。このファイル オプションにより、関数名のリストがツ
ールにより自動的に生成されます。
同様に、+Orarely_called は、比較的低い頻度で呼び出される関数をコンパイラに提示します。別の方法として、こ
れらの情報は、FREQUENTLY_CALLED および RARELY_CALLED プラグマを使用してソース コードに表すことができ
ます。
ESTIMATED_FREQUENCY プラグマは、ブロック スコープ プラグマで、現在のブロックに関する概算の相対実行頻度を
周囲の隣接するブロックと比較して提示します。これは、ループ本体内の平均トリップ数または then 句の実行時間の
割合を示すために使用できます。プラグマは、予想実行頻度やループ数などの定数を引き数として受け取ります。
例 8:ESTIMATED_FREQUENCY プラグマの一般的な使用例
if (condition) {
#pragma ESTIMATED_FREQUENCY 0.99
...
for (...) {
#pragma ESTIMATED_FREQUENCY 4.0
...
}
} else {
...
}
例 8 では、if 文の then 句内のコードで、99% の実行時間が予想されます (つまり、else 句は実行時間の 1%)。ル
ープは、平均 4 回の繰り返し実行が予想されます。
ESTIMATED_FREQUENCY プラグマは、与えられたソース コード条件でコンパイラが使用する制御の投機的実行の程
度に対するきめ細かい制御を、開発者に提供します。また、ループの平均繰り返し数を知ることで、コンパイラがデータ
プリフェッチが有効ではない可能性を判断できます。
強力なハイレベルの最適化
HP ハイレベル オプティマイザには、プロシージャ間オプティマイザ、ハイレベル ループ オプティマイザ、スカラー オプテ
ィマイザが含まれています。
プロシージャ間オプティマイザは、最適化レベル 2 以上で -ipo オプションを指定すると有効になります (たとえば、+O2
-ipo)。最適化レベル 4 (+O4 オプション) には、自動的に-ipo が含まれます。ハイレベル ループ オプティマイザは、
最適化レベル 3 以上 (オプション +O3 と +O4) で有効になります。スカラー オプティマイザは、他のハイ レベル最適化
と共に有効になります。
-ipo オプションは、アプリケーションのソース ファイルの一部または全部のコンパイル時に使用できます。-ipo を指
定して一部のモジュールをコンパイルすると、これらのファイルでモジュール間最適化が有効になります。このモードで
は、IPO 中にコンパイラにより一部のアプリケーションのみが解析されます。したがって、コンパイラは、アプリケーション
の残りの最適化を控えめに行なう必要があります。これにより、最適化の機会が一部失われる可能性があります。
最高のパフォーマンスを得るには、-ipo オプションを使用して、アプリケーションのすべてのソース ファイルをコンパイ
ルするのが有益です。このモードをプログラム全体モードと呼んでいます。このモードでは、コンパイラはアプリケーショ
ンの正確な解析を実行できるため、パフォーマンスの改善につながります。
ハイレベル オプティマイザは、PBO 情報を利用するため、PBO (オプション +Oprofile=use) と組み合わせて使用すると
より効果的です。たとえば、PBO データにより関数のインライン化が強化されます。PBO データは、間接的な呼び出し場
所で、最も可能性の高い呼び出しサイズを明確にし、ハイレベル オプティマイザが間接呼び出しをテスト呼び出しおよび
直接呼び出しに変換できるようにします。
アプリケーションのパフォーマンスは、現在次のように、プロシージャ間の最適化により向上します。
• メモリ参照と関数引数のプロシージャ間解析により、多くの種類の最適化を有効にし、改善できます。たとえば、レ
ジスタ プロモーションを含むロー レベル オプティマイザに対して、いくつかの追加の最適化機会を生み出します。
9
次の例を検討してみましょう。
void foo( int *x, int *y
{
... = *x; // load
*y = ... // store
... = *x; // load
}
)
1
1
2
次に示すようなポインタ x と y のプロパティについての追加情報がなければ、コンパイラは 2 つ目のロード命令
(load 2) を発行しなければなりません。なぜなら、ストア (store 1) がポインタ x の内容を上書きすることがあ
るためです。
プロシージャ間の解析の結果として、x と y がエイリアスしない (同じメモリ ロケーションを指さない) と分かってい
れば、コンパイラは *x の値をレジスタにプロモートし、このレジスタを再使用 (load 2) できます。
• 関数のインライン化は、呼び出しのオーバヘッドの削減、実行コードの局所性の改善、コード内での分岐数の削減
といった慣習的な利点の他に、命令のスコープが拡張されることにより最適化機会が増加し、より良い命令スケジ
ューリングが行なえるようになります。
このコンパイラのリリースでは、非常に大きいアプリケーションに合わせてインライン化フレームワークが再設計さ
れています。インライン化フレームワークは、新しい高速な基盤アルゴリズムを使用し、さらに、インライン化の決定
に新しい精巧なヒューリスティック セットを採用しています。
インライン化エンジンは、+O2 オプションにおけるモジュール内のインライン化でも利用されます。この最適化レベ
ルのインライン化では、インライン化のヒューリスティックのレベルを下げて、パフォーマンス向上に加えて高速なコ
ンパイル時間を保証します。
• 間接呼び出しプロモーションを有効にして、呼び出しグラフ全体を作成し、間接呼び出しをテスト呼び出しおよび直
接呼び出しに変換します。この方法は、PBO データが存在する場合、アプリケーションの特性に応じて、大幅なア
プリケーションの高速化が期待されます(測定では、特定のアプリケーションで最大 20%の改善)。
• ハイレベル オプティマイザは、デッド変数 (参照されないグローバル変数とスタティック変数) を削除し、アプリケー
ションの全体的なメモリ所要量を抑えることができます。
• オプティマイザは、割り当てられたものの一度も使用されないグローバル変数、スタティック変数、ローカル変数を
識別し、(追加のデッド変数を生成する可能性のある)デッド コードを削除します。
• ハイレベル オプティマイザは、モジュール内でのみ参照されるグローバル変数の変換により、シンボルをプライベ
ート シンボルに変換し、その変数へのアクセスをこのモジュール内からのアクセスのみに限定します。これにより、
ローレベル オプティマイザは、この変数への参照を最適化するうえで大きな自由が与えられます。
• デッド関数 (一度も呼び出されない関数) と冗長関数 (たとえば、重複したテンプレートのインスタンス化など) の除
去により、ワーキング セットが削減されるため、コンパイル時間が短縮され、クロスモジュールのインライン化の効
果を上げることができます。さらに、アプリケーションの合計コード サイズが縮小するため、キャッシュ ミスとページ
ミスの発生も少なくなります (パフォーマンスの改善につながります)。
• short 型データの最適化。short 型データ領域に割り当てられたグローバルデータとスタティックデータへのアク
セス シーケンスが効率化されます。プログラム全体モード (-ipo) では、コンパイラは、正確な解析を実行して、す
べてのグローバルデータとスタティックデータが short データ領域に収まるかどうかを判定し、収まる場合、その領
域にデータを割り当てます。データが収まらない場合、コンパイラは、最も安全な short データ サイズの閾値を判定
して、最大量のデータ アイテムが効率的に割り当てられるようにします。
• これは、+O2 オプション単独 (-ipo オプションなし) の場合に比べて有利です。最適化レベル +O2 では、オプショ
ン +Oshortdata、+Oshortdata=<threshold> を利用して同様の最適化を有効にできます。しかし、この方
法は、一般にアプリケーションの変更と発展に対応できません。
• 外部関数 (バイナリに含まれない関数) を呼び出す場合、リンカは小さな呼び出しスタブを導入します。コンパイラ
は、関数呼び出しが外部関数の呼び出しであると認識すると、呼び出しスタブをインライン化でき、これによりパフ
ォーマンスが改善します。
HP コンパイラは、関数が外部関数であることを示すプラグマ (#pragma extern) を使用して、関数プロトタイプに注
釈を付けるメカニズムをサポートしています。コンパイラ オプション -minshared (15 ページの「リンク モードの選択」
を参照) と共に使用すると、呼び出しスタブのインライン化を実現できます。
プログラム全体モードでは、もう -ipo オプションを付ける必要はありません。このモデルでは、コンパイラはどの関数
がアプリケーションで定義されており、どの関数が外部関数であるかを知っており、自動的に関数を適切にマークします。
プロシージャ間の解析フェーズを使用すると、ソースの問題点をさらに明らかにし、警告します。たとえば、変数が、異な
るソース ファイル内で互換性のない属性で宣言されている場合などがあります。
ハイレベル ループ オプティマイザは配列アクセス パターンに基づいて、次のような従来のループの最適化を行います
(ループ オプティマイザは +O3 または +O4 オプションで有効です)。
10
• ループ交換
• ループ分散
• ループ融合
• ループ アンロール
• ループ アンスイッチ
• ループのクローン生成
• 並列化
このような最適化により、配列アクセスの局所性が向上し、データ キャッシュを効率的に利用できるようになります。並
列化は、ループ本体の作業を利用可能な各プロセッサに分散します。
ループ オプティマイザは次の新しい最適化も行います。
• memset/memcpy タイプ ループの認識。基本的に、データ ブロックを別のメモリ位置にコピーするループの場合、
コンパイラは、コピーの方向などのループの特性を決定します。そしてループ全体を、高度に特化され最適化され
たコピー ルーチンの直接呼び出しに置き換えます。
リンカ
バック
エンド
ロード
モジュール
図 2:プロシージャ間最適化のビルド モデル
• ループのリロール。ユーザー コードの中には、手動でアンロールされたループが存在する場合があります。これら
の手動アンローリング形式は、通常、特定のマシン向けへのチューニングに由来しています。しかし、別のマシンで
は、この手動アンロールされたコードがうまく動作しない場合があります。コンパイラは、そのようなループ アンロー
ルを識別し、インクリメント文を削除してループ境界とインクリメントを調整することでリロールを試みます。次に、そ
のようなループ リロールをループ オプティマイザに通すと、マシンの特性に従って、最適なアンロール決定を行え
ます。ループ リロール後、ループ マージ パスを実行して、手動でアンロールされたループとその余剰ループをマー
ジします。
ハイ レベル スカラー オプティマイザは、制御フローの最適化と基本的なブロックのクローン生成だけでなく、式の簡素
化と正規化、SSA ベースのデッド コードの削除、コピーの伝播、定数の伝播などを行います。
プロシージャ間の最適化フレームワーク (最適化レベル +O2 以上の -ipo オプションで有効) は、非常に大規模なアプ
リケーションに対応できるように、再設計されています。
幸い、ユーザーの視点からは何も変更はありません。既存のビルド プロセスを変更する必要はありません。IPO とコー
ド生成がリンク時に実行されるため、リンク時間がかなり長くなる可能性があります。
内部ビルド モデルは、デフォルトのビルド モデルとは少し異なります。これについては、図 2 (明確にするため簡易化し
ています) で説明しています。
-ipo オプションで生成されたオブジェクト ファイルには、ユーザー コードの中間表現が含まれています。これらのファ
イルを IELF ファイルと呼びます。IELF ファイルは、IPO 時に最短時間でアクセスできるように設計されています。
デバッグ情報 (-g オプション) を含む通常のオブジェクト ファイルと比較して、IELF ファイルは通常 3 倍大きくなります。
IELF ファイルは完全な型情報を含める必要があるため、デバッグ情報を含まないオブジェクト ファイルと比較すると、か
なり大きくなる可能性があります。したがって、非常に大きなアプリケーションでは、ファイル システムの負担になる可能
性があります。elfdump ユーティリティを使用すると、与えられたオブジェクト ファイルが IELF ファイル (-ipo オプション
で生成) か、実際のオブジェクト ファイルか判断できます (elfdump の –f オプションを使用)。
11
IELF ファイルは、コンパイラのバージョン間で互換性が保証されていません。このため、コンパイラをアップデートした後
で、全ての再コンパイルを行う必要があります。
IELF ファイルは、プロシージャ間の分析と最適化フェーズで使用されます。その結果として、変換後の最終的な一時 IELF
ファイルが生成されます。IPO 時に必要なコア メモリの総量を最小化し、最高速のアルゴリズムの選択を保証するよう
最大の注意を払います (20 ページの「参考文献」の項目 12 と 13 を参照)。
IPO フェーズでは、一時 IELF ファイルを実際のオブジェクト ファイルに変換するためのターゲットを含む一時 Makefile
が生成されます。この変換は、be と呼ばれるスタンドアロン バックエンドで行われます。be には、ハイ レベル オプティ
マイザのほかに、コード ジェネレータとローレベル オプティマイザが含まれます。IPO フェーズでは、生成された
Makefile に対して並列モードで make が実行され、アプリケーションのリンクで必要な最終的なオブジェクト ファイルが
生成されます。このメカニズムはユーザーに公開されています。
be の並列プロセスのデフォルト数は、マシン上のプロセッサ数に設定されます。この数値は、環境変数 PARALLEL を
設定することで上書きできます(詳細は、make のマン ページを参照)。
この並列化により、複数プロセッサをもつマシン上で、コードの生成とロー レベル オプティマイザに費やされる時間が大
幅に短縮します。いくつかの逐次的なビルド プロセス (フロント エンド部分で make が並列に実行されない) では、+O4
オプションは +O2 オプションよりも高速であることが確認されています。しかし、一般には、+O4 オプションは +O2 オプ
ションの 2 倍低速になることはないと予測しています (アプリケーションのビルド メカニズムとビルド マシンの違いにより
異なります)。
精密な浮動小数点制御
HP のコンパイラは、インテル Itanium アーキテクチャ独特の強力な浮動小数点機能を、開発者が完全に利用できるよう
に設計されています。これらの機能により、HP コンパイラにより生成された浮動小数点コードや数学ライブラリは、デフ
ォルトのオプションや一般のコンパイラ オプションを使用して、非常に正確で、効率的な最適化を行うことができます。
-fpwidetypes オプションの下では、C および C++ 数学ライブラリのヘッダーが 80 ビットの浮動小数点型を含む関
数やマクロの名前を定義し、C の数学ヘッダーが 128 ビット long double 型を含む関数やマクロの代替名を定義し
ます (表 1 を参照)。型名 extended および quad は、業界規約によるものであり、Itanium ベース システム間で実装
が異なる long double 型の特定フォーマットに依存しない型名を提供することで、移植を容易にしています。
表 1. 浮動少数点方型の接尾辞とマクロ
型
名前
関数の接尾辞
マクロ
float80(80 ビット
型)
extended (defined in
math.h, float.h,
complex.h, and stdlib.h)
w (logw など)
W (HUGE_VALW など)
EXT_ (EXT_MAX など)
long double また
は float128 (128
ビット型)
quad (math.h, float.h,
complex.h, stdlib.h 内で
定義)
q (logq など)
Q (HUGE_VALQ など)
QUAD_ (QUAD_MAX など)
HP C および C++ コンパイラでは、-fpeval={float|double|extended} オプションにより示される 3 つの浮動
少数点評価方法から選択できるようになっています。-fpeval オプションにより、広い値域と精度を採用している IA32 プラットフォームからのプログラムのインポートが容易になり、また、狭い値域での評価が丸め誤差、オーバーフロー、
アンダーフローに敏感である部分の強さを向上させることができます。
• float(デフォルト) は、浮動小数点演算および浮動小数点定数をセマンティック型に対して評価する C99 固有
の評価方法を選択。
• double は、浮動小数点演算および浮動小数点定数を広い値域と精度の double 型に対して評価し、それ以
外の演算および浮動小数点定数をセマンティック型に対して評価する、C99 固有の評価方法を選択。
• extended は、float と double 型の演算および浮動小数点定数を広い値域と精度の extended 型に対
して評価し、それ以外の演算および浮動小数点定数をセマンティック型に対して評価する方法を選択。
いくつかの HP コンパイラ オプションでは、浮動小数点演算の精度と特殊な値の処理を制御できます。
• +Ofltacc={strict|default|limited|relaxed} は、浮動小数点演算の精度を制御します。
• strict は、FMA ( Floating Multiply-Add) 統合のような短縮を禁止します。これは、ソース コード内の必要な
スコープで、#pragma STDC FP_CONTRACT OFF を使用して表現することもできます。
• コンパイラのデフォルトである default を選択すると、C99 の #pragma STDC FP_CONTRACT ON によ
る短縮 (FMA 統合) を許可しますが、結果の値を変更する可能性のあるその他すべての浮動小数点の最適
化を禁止します。短縮は、ほとんどのアプリケーションで適用可能ですが、特定の値域や精度に丸められる操作
に依存しているアプリケーションなどは (場合により、依存していないアプリケーションでも)、短縮により破損し
てしまう可能性があります。
12
• limited は、default と似ていますが、さらに、無限大、NaN (Not A Number)、ゼロ符号の生成と伝播
に影響する可能性のある浮動小数点の最適化 (x*0.0 の 0.0 への置換など) を許可します。
• relaxed は、limited の特性を持ち、さらに丸め誤差が変わる可能性のある浮動小数点の最適化 (式の
並べ替え。括弧内の場合も含む) も許可します。relaxed オプションにより、コンパイラは、わずかに精度の
低い数学関数を呼び出すことで、パフォーマンスを向上させることができます。
• +Osumreduction オプション (AR1204 の新機能) を使用すると、浮動小数点の精度に関わらず SUM リダクシ
ョンの最適化を有効にします。通常、SUM リダクションの最適化は C/C++ コンパイラの +Ofltacc=relaxed
オプション下でのみ有効です (Fortran 言語標準では、デフォルトで有効です)。しかしこのオプションを使用すると、
+Ofltacc オプションがどのような設定であっても、SUM リダクションの最適化を行なえます。SUM リダクションに
含まれる部分的な合計の算出のプログラム実行順序は不要だが、他の計算では正確さが必要なプログラムにとっ
ては有用です。これに対し、+Onosumreduction オプションは、+Ofltacc オプションがどのように設定されて
いても、SUM リダクションの最適化を禁止します。
• +Ocxlimitedrange オプションは、C99 無限大プロパティを満たすために、複雑な乗算、除算、および cabs
演算が必要ではないことを示し、extended および long double バージョンが頻繁にオーバーフローやアンダ
ーフローになる可能性があります。
• この機能は、ソース コードの必要なスコープで、#pragma STDC CX_LIMITED_RANGE ON を記述することでも
選択でき、+Ofltacc=limited および +Ofltacc=relaxed により有効化されます。
• +FPD オプションまたはライブラリ呼び出し fesetflushtozero(1) は、0 に初期化するアンダーフロー モード
を設定します。
その他のオプションでは、浮動小数点コードおよび数学ライブラリ関数の特化した特性を利用できます。
+Ofenvaccess オプションを使用すると、浮動小数点制御モードや例外フラグにアクセスするための <fenv.h> 機能
を安全に使用できます。この機能は、ソース コード内の必要なスコープで、#pragma STDC FENV_ACCESS ON を記
述することでも利用できます。
+Olibmerrno オプションは、errno を設定する数学関数と、IEC 60559 の実装で、戻り値が C99 とは異なる、HP
PA-RISC および Unix 95 用にドキュメント化された戻り値を提供します。デフォルトの +Onolibmerrno オプションは、
errno を設定しない関数を提供します。
広範なインライン アセンブリ
インライン アセンブリ組み込み関数を使用して、C または C++ プログラムに機械語レベルのコードを埋め込むことがで
きます。これらの組み込み関数は、<machine/sys/inline.h> に定義された、使いやすいインタフェースを使用し
て実装されます。このヘッダー ファイルをインクルードしていれば、コンパイラでは、正しい値とインライン命令の引き数
の使用が保証されます。
インライン アセンブリ組み込み関数の使用法を説明したマニュアルは、オンラインで入手できます。
http://h21007.www2.hp.com/dspp/tech/tech_TechDocumentDetailPage_IDX
/1,1701,3748,00.html
13
Itanium ベース アプリケーションのチューニング
アプリケーションのチューニングとは、基本的には次の 2 つの手順を反復するプロセスです。
アプリケーション内のホット スポットまたはアプリケーションの全般的なパフォーマンス問題を特定する。
ホット スポットを最適化し、パフォーマンス問題を解決する。
HP は、ホット スポットを特定し、Itanium プロセッサ ファミリのシステム上でのアプリケーションのパフォーマンスを特徴
づける新しいツールを開発しました。次の項では、これらのツールの使用方法と、アプリケーションのパフォーマンスをチ
ューニングするその他の技術について説明します。
プロファイリング
HP では、次の 2 つのパフォーマンス解析ツールを提供しています。
•
HP Caliper – このパフォーマンス解析ツールを使用すると、数種類のパフォーマンス データにアクセスできます。
HP Caliper は、アプリケーション コール グラフから命令レベルのイベントまで、3 つのパフォーマンス測定レベル
を提供します。グローバル測定では、キャッシュ ミス、TLB ミス、分岐予測のミス、パイプライン ストール、実行命令
など、重大なパフォーマンス要素に関する全体的な値をレポートします。グローバル測定は、パフォーマンス問題を
発見する手っ取り早い方法です。サンプル測定は、グローバル測定と同じパフォーマンス メトリックスをレポートし
ますが、それらは、アプリケーションの実行時にサンプル採取されたもので、プログラム位置と相関関係にあります。
精密測定は、正確な関数呼び出し数、関数カバレッジ、コール グラフ、基本ブロック アーク数などをレポートします。
HP Caliper は、アプリケーションの実行時に動作するため、特別のコンパイラ オプションを指定してアプリケーショ
ンをビルドする必要はありません。
•
HP-UX gprof – このツールは、アプリケーションのホット プロシージャを示し、どのホット パスがそのホット プロシ
ージャを呼び出しているかを示します。この情報から、コンパイラ オプションやプラグマ、またはアルゴリズムの改
良によるチューニングを、アプリケーションのどのプロシージャまたはどのセクションに適用すれば最も効果的かを
見極めることができます。gprof でアプリケーションを使用するためには、HP コンパイラで -G オプションを指定する
必要があります。
表 2. HP パフォーマンス解析ツールとその用途
パフォーマンス ツール
用途
HP Caliper
アプリケーションのパフォーマンスに関する最も詳細なビュー。アプリケーションでのパフォーマンス問
題の位置付けと、パフォーマンスの最適化の影響を測定する場合に使用できます。
+Oprofile=collection オプションでビルドされたプログラムを実行する場合に自動的に実行さ
れます。
gprof
パフォーマンスに関する高速で高レベルのビュー
ヘッダー ファイルのインクルード
古い C アプリケーションでは、libc などのシステム ライブラリ用のヘッダー ファイルがインクルードされていないこと
がよくあります。たとえば、<stdio.h> は printf を呼び出すすべてのファイルでインクルードする必要がありますが、
しばしばインクルードされないことがあります。C におけるデフォルトの引き数と戻り値の型により、明示的な先行プロト
タイプや宣言を持たない関数の呼び出しが可能で、また、これらの呼び出しは通常正しく動作します。特にデフォルトの
int 型とポインタ型が同じサイズである、従来の 32 ビット データ モデルの場合には正しく動作します。
Itanium ベースの HP-UX システムのヘッダー ファイルには、HP コンパイラが呼び出しを静的にライブラリ関数にバイン
ドして最適化できるようにする、多様なプラグマが用意されています。コンパイラはコンパイル時に、システム ヘッダー内
の #pragma BUILTIN または #pragma BUILTIN_MILLI で識別される安全な場所で、ライブラリ呼び出しをバイ
ンドします。これらの関数の呼び出しは、コンパイラにより最適化され、コンパイラは、関数をインライン化するか、呼び出
しを高速ルーチンに置き換えるか、または呼び出しの周囲を強力に最適化します。また、ヘッダー ファイルには、システ
ム ライブラリ ルーチンを外部宣言するプラグマが含まれているため、共有システム ライブラリ呼び出しの最適化も可能
です。こうした変換により、パフォーマンスが大幅に向上するアプリケーションもあります。
プロセッサのスケジューリング
インテル Itanium プロセッサ ファミリのメンバーは、各メンバーで異なるリソース制約、命令遅延、その他のスケジューリ
ング基準を持っています。HP コンパイラにより、開発者はプロセッサ ファミリの特定メンバー用のアプリケーションを最
適 化 す る か 、 ま た は す べ て の Itanium プ ロ セ ッ サ に 適 し た ア プ リ ケ ー シ ョ ン を 作 成 す る か を 、
+DS{blended|itanium|itanium2|native} コンパイラ オプションを使用して選択できます。
14
• デフォルト オプションの +DSblended は、すべての実装で適度に正しく実行されるコード スケジューリングを指定
します。
• +DSitanium および +DSitanium2 オプションは、それぞれのプロセッサ用に最適化されたコードを選択します。
• +DSnative オプションは、コンパイルが実行されるシステムの種類に最も適するように、コードをスケジュールす
るようにコンパイラに要求します。
HP では、新しいプロセッサの導入に伴い、+DS シリーズのオプションに新しいオプションを追加していく予定です。
これらのオプションを使用する際は注意が必要です。あるプロセッサ向けにコンパイルされたアプリケーションが、ほか
のプロセッサでの実行には最適でない場合があります。たとえば、Itanium2 (+DSitanium2) プロセッサ用にスケジューリ
ングされたコードは、Itanium プロセッサで実行した場合、+DSitanium オプションでコンパイルされたコードに比べて実
行速度が 5 ~ 40% 低下することがあります。相対的なパフォーマンスの違いは、アプリケーションにより異なります。浮
動小数点演算を多用するコードは、整数コードよりもスケジューリング モデルに敏感な傾向があります。+DSblended
スケジューリング モデルは、既存のすべての実装で、ある程度正しく実行されるコードを生成しようとするハイブリッド モ
デルであり、新しい Itanium プロセッサのリリースに従って進化し続けます。AR1204 コンパイラでは、+DSblended モ
デルは +DSitanium2 モデルと同等です。
最適のパフォーマンスを得るには、インテル Itanium プロセッサ ファミリの将来のメンバー向けに、アプリケーションの再
コンパイルが必要になる場合があります。ただし、バイナリの互換性は、スケジューリング オプションの選択に関係なく
保持されます。
リンク モードの選択
デフォルトでは、すべての HP コンパイラは -dynamic オプションの指定を想定しています。コンパイルにより生成され
るオブジェクト ファイルは、動的リンクを使用し、共有ライブラリに包括できます。オブジェクト ファイルを、共有ライブラリ
ではなく、実行可能ファイルにリンクする場合は、-exec オプションが適切です。-exec オプションは、定義されたすべ
てのグローバル シンボルを実行可能ファイル内で解決するようにコンパイラに指示します。これにより、通常、ロードや
ストアが高速に実行できるようになります。-minshared オプションは、アーカイブ ライブラリが使用可能な場合は、共
有ライブラリではなく、アーカイブ ライブラリを使用するようにコンパイラに指示します。これにより、パフォーマンスが向
上する可能性があります。このオプションは、システム ヘッダー ファイル内に適切なプラグマで宣言されているシンボル
を除き、すべてのシンボルを実行可能ファイル内で解決するようにコンパイラに指示します。
ページ サイズの拡大
アプリケーションのデータ TLB または命令 TLB のミス率が高い場合、データや命令のための仮想メモリ ページ サイズを
拡大するように要求すると、さらにパフォーマンスを向上させることができます。HP Caliper は、アプリケーションで TLB
ミス率が高くなっている場合、それを報告します。ページ サイズの拡大は、リンカの +pd および +pi オプション、または
chatr(1) コマンドを使用して指定できます。
回復コードの削除
デフォルトでは、HP コンパイラは制御の投機的実行によるロードに対して回復コード (5 ページの「制御の投機的実行」
を参照) を生成します。投機的実行命令から生成された NaT トークンは、NaT トークンにより示される実際の値が実行
時に必要となった場合、回復コードを実行します。回復コードが存在するため、プロセッサが正確な例外を発行している
間、投機的なロードから生じたページ フォルトと TLB ミス フォルトを延期できます。
+Onorecovery コンパイラ オプションは、コンパイラに制御の投機的実行によるロードに対して回復コードを生成しな
いように指示します。コンパイラは、NaT トークンを検出する命令や必要な値を再計算する回復コードを削除できるため、
回復コードがない場合、実行時のパフォーマンスを向上させることができます。投機的なロードが通常実行されているパ
スから登用されている場合は、チェック命令および回復コード実行の削除により、パフォーマンスを向上させることができ
ます。
ただし、+Onorecovery オプションが常に適切なわけではありません。このオプションを使用することにより、投機的に
実行されるロードに対するページ フォルトと TLB ミス フォルトを処理するようプロセッサに強制します。任意の TLB のミ
ス ペナルティ は、2000 サイクル程度まではチェック命令の位置ではなく、制御の投機的なロードの位置で起こります。
パスが実行されない場合など、投機的に実行されるロードにより生成された値を使用しない場合は、TLB のミス ペナル
ティはパフォーマンスを低下させる要因になります。また、アプリケーションが、ロードの本来の場所で発生する、明白な
障害に依存している場合、+Onorecovery を使用しないでください。
HP Caliper のデータで、+Onorecovery が使用されている場合の TLB ミス率に与える影響を確認できます。
+Onorecovery が原因で、いくつかの重要な分岐で TLB ミス率が大きくなっているような場合は、これらの位置の結果
コードが制御の投機的実行を過剰に使用している可能性があります。このような過剰な使用は、
ESTIMATED_FREQUENCY プラグマにより制御できます。
15
アプリケーション特性の記述
HP コンパイラは、アプリケーションにより使用されるコーディング スタイルを記述するいくつかのオプションをサポートし
ています。これらのオプションにより、コンパイラはアプリケーションの動作について仮定できます。次に示すコーディング
のガイドラインはやや面倒なものかもしれませんが、このようなオプションによりパフォーマンスが大幅に向上することが
あるため、価値のあるものです。
• オプション +Otype_safety={off|limited|ansi|strong} は、コンパイルされるコードが使用する安全ル
ールの型を記述します。
• off はデフォルトです。エイリアスが型の間で自由に発生することを示します。
• limited は、ANSI エイリアス ルールに従うことを指定します。名前なしオブジェクトはエイリアシングでは不
明型と同様に扱われます。
• ansi は、ANSI エイリアス ルールに従うことを指定します。名前なしオブジェクトは名前付きのオブジェクトとして
処理されます。
• strong は、ANSI エイリアス ルールを指定します。ただし、文字型の値を経由したアクセスによりほかのオブジェ
クトに接触することは許されません。また、コンパイラは、フィールド アドレスが取得されないと想定します。
• +Onoptrs_to_globals オプションは、静的に割り当てられたデータ (ファイル スコープのグローバル、ファイル
スコープの静的データ、関数スコープの静的データを含む) にポインタ経由でアクセスできないことを、コンパイラに
宣言します。反対に、+Optrs_to_globals オプションは、静的に割り当てられたデータにポインタ経由でアクセ
スできることを想定します。
• +Oparmsoverlap および +Onoparmsoverlap オプションは、関数パラメータがほかのパラメータと重複する
かどうかを宣言します。Fortran の場合、デフォルトは +Onoparmsoverlap で、引き数が別の引き数または共通
ブロックの変数と重複しないことを示します。+Oparmsoverlap オプションでは、このような重複が有効になりま
す。C および C++ の場合は、ポインタ引き数から間接的にアクセスされたメモリが、別のポインタ引き数で間接的
にアクセスされるメモリや静的に割り当てられたデータと重複する場合があるため、+Oparmsoverlap がデフォ
ルトになっています。+Onoparmsoverlap オプションによる宣言は、そのような重複が生じない際に使用します。
コンパイラだけでは、これらのガイドラインがいつ必要になるか判別できません。また、これらのガイドラインに対する違
反を診断することもできません。しかし、プログラム全体モードでは、コンパイラが分析を行って、静的に割り当てられた
データがポインタを通してアクセスされるかどうかを検出するため、+O[no]ptrs_to_globals オプションは必要あり
ません。さらに、コンパイラは、プログラム全体モードが指定されている場合には、+Onoptrs_to_globals オプショ
ンの間違った使用を検出し、警告します。
表 3. 汎用チューニング オプションとその適用時期
最適化タイプ
適用時期
システムヘッダーファイルの
インクルード
呼び出されたすべてのシステムライブラリ関数に
ついてのヘッダーを含まない古い C コードの場
合
プロセッサ用の最適化
特定のプロセッサで最大のパフォーマンスを得る
場合
複数のプロセッサをサポートする場合
リンクモードの選択
共有ライブラリではなく実行可能ファイルを作成
する場合
利用可能なアーカイブライブラリを選択する場合
ページサイズの拡大
回復コードの削除
アプリケーション特性の記述
データ(または命令)TLB のミス率が高い場合
メモリアクセスに関連するシグナル処理に依存し
ない、非数値的アプリケーションの場合
オプション
+DSblended
+DSitanium
+DSitanium2
+DSnative
-exec
-minshared
-Wl,+pi -Wl,+pd
PBO データを利用した制御の投機的実行が可
能な場合
+O[no]recovery
アプリケーションが特定のガイドラインに従うこと
が分かっている場合
+O[no]ptrs_to_globals
+Otype_safety
+O[no]parmsoverlap
プロファイル ベースの最適化によるチューニング
プロファイル ベースの最適化 (PBO) は、次の場合に効力を発揮します。
• アプリケーションに、膨大な数の制御フロー分岐が含まれている場合
• アプリケーションに、多数の間接的な分岐 (たとえば、C++ 仮想関数呼び出し) が含まれており、-ipo オプション
が使用されている場合。
16
• HP Caliper データが、分岐の予測ミス率が高いこと、case 文のレイアウト最適化の数が多いこと、ホット分岐での
if 変換の数が多いことを示す場合。
• 代表的な入力セットが容易に入手できる場合、または利用可能なプロファイル データが PBO オプションやプラグ
マに変更可能な場合。
• +Onorecovery オプションが、TLB のミス率が高いことを示している場合 (15 ページの「回復コードの削除」を参
照)。
• HP Caliper データが、データ キャッシュのパフォーマンスが低いこと、アプリケーションにリンク リストの横断、多数
の大域変数または静的変数が含まれていることを示しているとき。
• アプリケーションに、2,3 回だけ繰り返すループが含まれている場合。
整数コードの場合、PBO を実行することにより、アプリケーション パフォーマンスの 5 ~ 40% 程度の向上が見込まれ
ます。浮動小数点の場合、これよりやや控えめな効果となります。
浮動小数点数値コードのチューニング
これまで説明してきたパフォーマンス戦略により、浮動小数点に関するパフォーマンスを向上させることができます。たと
えば、+O2 での最適化や PBO により、大半の浮動小数点コードの速度が向上します。+03 の最適化ではさらにコード
は高速になり、ループ多用型のコードのパフォーマンスは劇的に向上します。+O3 オプションでは、コンパイラはループ
変換 (交換、融合、分散など) や数学ライブラリ ルーチンのユーザー コードへのインライン化など、特別な最適化を実行
します。特に、HP Caliper で、データ キャッシュや TLB のミス率が高い値を示している場合は、+O3 で実行される最適
化が大きな効力を発揮します。
+O3 では、適切なヘッダー ファイルがインクルードされているか、+Olibcalls オプションが指定されている場合、コン
パイラは一般的に使用されている数学関数 (log、exp、sin、cos など) の多くをインライン化します。これにより、特にル
ープ内での呼び出しに対しては、パフォーマンスが飛躍的に向上し、関数の動作に影響することもありません。
従来の一般的な最適化戦略は、浮動小数点の品質を損なうことなく適用できます。以下に、追加すべき提案を示します。
• 数学ライブラリ関数を含む特定の最適化は、ソース ファイルにその関数の宣言を行う <math.h> のような数学ヘ
ッダーがインクルードされている場合にのみ実行されます。
• コンパイラは特別な浮動小数点セマンティクスの制御下 (12 ページの「精密な浮動小数点制御」を参照) にあって
も最適化を行いますが、これらの制御は最適化を制限します。最適化を必要としないコードの場合、パフォーマンス
が低下することもあります。最高のパフォーマンスを得るには、コンパイル オプション +Ofenvaccess を使用して、
コンパイル ユニット全体を対象にするのではなく、#pragma STDC FENV_ACCESS ON を使用して必要なコード
のみを囲み、最小ブロックを対象にします。同様に、対象となる最小ブロックで #pragma STDC FP_CONTRACT
OFF を使用し、+Ofltacc=strict オプションでコンパイルするのではなく、+Ofltacc=default オプションで
コンパイルします。
• +Olibmerrno オプションは、コンパイル単位内で数学関数が errno を設定する必要がある場合のみ効果的
です。errno の代わりに例外フラグの照会を検討してみてください。
• -Wl,-a,archive_shared を指定したリンクは、アーカイブ バージョンの libm にリンクするため、非常に効
率的な呼び出しシーケンスを生成します。
以下にあげるテクニックでは、大幅なパフォーマンス向上を実現できますが、例外的な、特殊な入力を処理する能力を
低下させてしまう可能性もあります。以下のテクニックは、精度に関して寛容な浮動小数点モデルを使用するシステム、
十分にテストされたシステム上で正しく動作することが実証されているアプリケーションについて、そのパフォーマンスを
さらに改善したい場合、最も適しています。
• +Ofltacc=limited は、アプリケーションが無限大、NaN、符号付ゼロの特定の処理に依存していない場合に
適しています。このオプションは、ほとんどのコードのパフォーマンスが飛躍的に向上することはありません。
• +Ocxlimitedrange または #pragma STDC CX_LIMITED_RANGE ON は、複雑な乗算、除算、または
cabs() 関数を使用する C アプリケーションに適しています。また、これらの演算に対する模範的な式 (オーバ
ーフロー、アンダーフロー、無限大値などの特別の配慮が不要なもの) は許容されます。HP-UX では、float
および double の複雑な演算は広い内部値域と精度を使用して実装することで、早期オーバーフロー、アンダー
フロー発生の問題を解決しています。
• +Ofltacc=relaxed は、アプリケーションが +Ofltacc=limited の基準を満たし、精度の条件がゆるや
かな浮動小数点モデルで正しく実行されることがわかっており、低位結果ビットの再現性が重要視されないとき、
+Ofltacc=limited を上回るパフォーマンス効果を発揮します。
• +Osumreduction は、アプリケーションが、部分的な合計の算出に厳密な計算順序を必要としない SUM リダク
ションを含んでいるが、+Ofltacc=relaxed を使用できない場合に、+Ofltacc=limited 以上にパフォーマ
ンスを向上させることができます。
17
• +FPD または fesetflushtozero(1) の呼び出しは、正常でない結果値の代わりに返されるゼロを、アプリ
ケーションが許容できる場合に適しています。0 への初期化モードを使用すれば float 型による処理速度が飛
躍的に向上します。
アルゴリズムを新しいコードで再設計または再実装することが可能な場合、次のテクニックで大幅なパフォーマンス向上
が得られます。
• 80 ビット extended 型の演算は、本質的には float 型または double 型と同じ速度です。extended 型数
学関数の速度は通常、対応する double 型関数の約 0.7 倍です。余分な精度や値域により、丸め誤差やアンダ
ーフローおよびオーバーフロー状態を処理するための特別なコードへの分岐を削除できる場合、全体的なパフォー
マンスが向上する場合があります。さらに、extended 型の拡張された値域および精度により、よりシンプルで、維
持しやすい、堅牢なアプリケーション コードを生成できます。また、128 ビット long double (quad) 型 (この
型の関数は通常 extended 型の対応ルーチンに対して 0.25 倍程度の速度) も、局所的に非常に高い精度が必
要とされる場合、高パフォーマンスのコードと考えられます。
• インライン アセンブリにより実装の一部を置き換えます。
プログラム モジュール間のチューニング
コンパイラ オプション -ipo は、クロスモジュール最適化を要求します (オプションで PBO と結合して)。-ipo の使用後
に収集された HP Caliper のデータが、命令キャッシュや TLB のミスの増加を示している場合、おそらくこれはインライン
化が過剰に行われたことを示しています。この場合は、+Oinlinebudget オプションでインライン化を制限します。
柔軟な最適化の実行
コンパイラ オプション +Ofast および +Ofaster は、整数主体のさまざまなアプリケーションにとって、安全で非常に効果
的な、使用頻度の高い最適化オプション セットを使用するようにコンパイラに指示します。+Ofast と +Ofaster に含まれ
る機能は、各リリースで進化していくと考えられますが、現在の +Ofast に含まれるオプションは以下のとおりです。
• +O2 : レベル 2 の最適化を要求します。
• +Onolimit : 大規模なプロシージャの完全な最適化を可能にします。ただし、コンパイル時間は長くなります。
• +Olibcalls : 適切なシステム ヘッダー ファイルがインクルードされていない場合も、いくつかの周知のライ
ブラリ ルーチンの呼び出しのインライン化または最適化を可能にします。
• +Ofltacc=relaxed(12 ページの「精密な浮動小数点制御」を参照)。
• +FPD : ハードウェア上で 0 への初期化を伴う丸めモードを有効にします。
• +Dsnative : コンパイルが実行されるシステムのタイプに特化したコード スケジューリングを指示します (28
ページの「プロセッサのスケジューリング」を参照)。
• -Wl、+pi、4M と -Wl、+pd、4M を使用すると、アプリケーションがそれぞれ 4 M バイトの命令仮想メモリ ペ
ージと 4M バイトのデータ仮想メモリ ページを使用できるようになります。
• -Wl、+mergeseg を使用すると、ダイナミック ローダーは、実行時にロードされる共有ライブラリのデータ セグメ
ントをマージします。このオプションにより、カーネルは大きなサイズのページテーブル エントリを使用できます。
+Ofaster オプションは、+Ofast +O4 のエイリアスであるため、クロスモジュールの最適化には理想的です。
+Ofast および +Ofaster の双方で +Ofltacc=relaxed を暗黙に指定するため、さらに厳密な浮動小数点処理
が要求される浮動小数点コードのチューニングには、単独では適していません。ただし、コンパイラによる一般的な左か
ら右へのオプション処理を利用すれと適した状態になります。たとえば、+Ofast +Ofltacc=strict は、+Ofast
により暗黙に指定される +Ofltacc=relaxed の設定を、後の +Ofltacc=strict が上書きするようにコンパイラ
に指示します。同様に、+Ofast +FPD により、デフォルトの段階的アンダーフロー モードが可能になります。
インライン アセンブリの使用
HP の C および C++ のインライン アセンブリのサポートにより、ソース レベルの構文から生成することが困難な、強力
な インテル Itanium 命令を直接利用できます。インライン アセンブリは、C および C++ の拡張機能として実装されてい
ます。追加のヘッダー ファイルをインクルードするだけで、インライン アセンブリを使用できます (ほかの変更は一切必
要ありません)。特定のアプリケーションについては、インライン アセンブリの使用によりパフォーマンスが向上し、コンパ
イラが単独で提供できる機能を超えた、重要な機能にアクセスできるようになります。
• マルチメディア アプリケーションのパフォーマンスは、インライン アセンブリにより飛躍的に向上します。これは、マ
ルチメディア用に多くのメリットを与える命令の多くを、コンパイラが直接生成できないためです。
• HP-UX コンパイラおよびライブラリにより、標準の言語機能と無理のない拡張機能を通して、アーキテクチャのほと
んどの浮動小数点機能を利用できます。80 ビット extended 型、fma() 関数、isinf および isunordered
などの照会マクロはすべて、標準の言語機能と無理のない拡張機能により利用できます。低レベルの浮動小数点
コードを記述する場合でも、インライン アセンブリを適切に使用することで、frcpa および frsqrta 命令、82 ビ
ット レジスタ、代替ステータス フィールドなどのアーキテクチャ機能の利用において、メリットを享受できます。
18
最適化に関する問題のトラブルシューティング
最適化せずにコンパイルしたときには隠れていたアプリケーション内の問題点が、最適化により表面化する場合があり
ます。以下にその典型的な例を示します。
• オブジェクト範囲を超えてメモリにアクセスするポインタの計算は、言語標準により未定義となります。このような標
準に準拠しないポインタ計算を使用してデータにアクセスすると、コンパイラが addp4 (ポインタ加算) 命令を使用
するため、32 ビット モードではエラーになります。
• ポインタの加算命令は、32 ビット ポインタにオフセットを加算してアドレス計算を行いますが、このポインタは結果
のポインタと同じアドレス領域を指していなければなりません。しかし、アプリケーションが標準に準拠しないポイン
タ計算を使用した場合、コンパイラはこの条件を順守できなくなることがあり、その結果不正なポインタ アクセスが
発生します。このようなポインタ計算を行わないようにアプリケーションを書き換えることができない場合は、
+Ocross_region_addressing オプションを使用してこの問題を回避してください。
• +Oinitcheck オプションは、初期化されていないすべての変数を検出して初期化するように、コンパイラに指示
します。アプリケーション コードに初期化されていない変数が含まれている場合、最適化後に予期しない動作を示
すことがあります。このオプションが指定されていない場合、コンパイラは、すべてのパスで全く初期化されていな
い変数を検出し、警告します。変数が一部のパスでのみ初期化されていない場合は、デフォルトではこのような変
数は検出されないためエラーになります。
• 同様に、+Oparminit オプションは、呼び出し場所で未指定の関数パラメータすべてをゼロに初期化するようコン
パイラに指示します。このオプションが指定されていない場合、これら未指定のパラメータには、それより前の計算
処理により NaT トークンが格納される可能性があります。この NaT トークンが使用されてしまった場合に不正な
動作が発生します (5 ページの「制御の投機的実行」を参照)。
• C および C++ 言語標準によると、ユーザー コードで符号付き整数演算のオーバーフローが発生すると、動作が
未定義になります。本コンパイラでは、最適化の間、そのようなオーバーフローが発生しないと仮定します。たとえ
ば、コンパイラはループ内の整数アキュムレーションがオーバーフローしないと仮定して、ループ本体内の符号拡
張演算を除去します。算術演算のオーバーフローに対する動作に依存するプログラムは、最適化が行われた後、
動作が異なる可能性があります。+Ointeger_overflow=conservative オプションを使用すると、オーバー
フローしないよう、コンパイラの最適化処理時の仮定を抑制できます。
またコンパイラは、コンパイラ自体が構築した算術式は、オーバーフローしないと仮定します。たとえば、一次テスト置換
の最適化により、整数の比較で使用されるループ不変変数がスケール アップします。コンパイラが、スケール変数がオ
ーバーフローしないことを常に保証することは不可能であり、現実的でもありません。しかし、表現できる範囲の境界値
付近の変数をプログラムが含んでいる場合は、オーバーフローの状況がコンパイラにより生成されます。この最適化は、
+Ointeger_overflow=conservative オプションや +Ointeger_overflow=moderate オプションを使用す
ることにより、抑制できます。後者のオプションは、AR1204 で新しく追加され、一次テスト置換の最適化に含まれる変
数のスケーリングのみを回避します。このオプションは、スケーリングの結果、オーバーフローするが、
+Ointeger_overflow=conservative オプションは不必要かつパフォーマンスを低下させる場合に使用されます。
特定の浮動小数点の丸め動作に依存するアプリケーションをコンパイルする場合は、+Ofltacc=strict が適してい
ます。デフォルトでは、コンパイラが実行する値変更の最適化のみが短縮の統合になります。中間の丸めの対象となら
ないため、結果の値は全般的に精度が高くなります。ただし、浮動小数点のアプリケーションの中には、正確な結果を出
すために中間の丸め操作に依存するものもあります。
開発者は、最適化に成功しなかった最適化レベルと、それより低いレベル (最適化が成功するレベル) でコンパイルした
アプリケーションのオブジェクト ファイルのサブセットをリンクさせることにより、最適化されたコードで発生する問題の範
囲を絞り込むことができます。この方法でオブジェクト ファイルのバイナリ検索を行うことにより、実行エラーの原因とな
るオブジェクト ファイルをすばやく特定できます。オブジェクト ファイルに複数の C または C++ ルーチンが含まれてい
る場合、ソース ファイル内のルーチンに対して #pragma OPT_LEVEL n プラグマを使用した別のバイナリ検索を実
行することにより、通常、問題のあるルーチンを特定できます。このプラグマは最適化レベルを引き数の値まで下げ、そ
の最適化レベルが、ファイルのそれ以降の部分に対して引き続き維持されるか、または他のプラグマにより最適化レベ
ルが再度設定されるまで維持されます。また、+O0=name オプションを使用して、選択した関数の最適化をオフにするこ
ともできます。Fortran アプリケーションの場合は、fsplit ツールにより、1 つのソース ファイルが複数の単一ルーチン フ
ァイルに分割されます。
19
表 4. 最適化コードに関する問題のトラブルシューティングに使用するオプションおよびプラグマ
オプション
用途
+Oinitcheck
初期化されていない可能性のあるすべての変数をゼロに初期化。
+Oparminit
NaT 値を避けるため、すべての呼び出し側にある未指定の関数パラメータをゼロ
に初期化。
+Ofltacc=strict
短縮を含む、値変更の最適化をすべて回避。
+Ocross_region_addressing
32 ビットモードで、ポインタの加算命令を、標準に準拠しないポインタ計算が正しく
実行されるように変更。パフォーマンスは多少低下する。
+O0=name[,name]...
名前付き関数についての最適化をオフ。
#pragma OPT_LEVEL n
指定の最適化レベルで後続のコード (次の opt_level プラグマまで) のコンパイルを
実行するように指示する C/C++ プラグマ。コマンド行の最適化レベルと同じか、そ
れよりも低い最適化レベルのみ指定できる。
+Ointeger_overflow=conservative
コンパイラにより構築される変換式がオーバーフローしないよう、コンパイラにほとんど仮定を
させない。
+Ointeger_overflow=moderate
コンパイラにより構築される変換式がオーバーフローしないよう、コンパイラに適度に仮定を
させる。
20
参考文献
製品の追加機能と利用可能な情報は、HP の開発者向け Web サイトで入手できます。
http://h50146.www5.hp.com/products/software/oe/hpux/developer/ (日本語)
http://devresource.hp.com/drc/index.jsp (英語)
HP Caliper の広範なドキュメントと技術文書は、次の Web サイトから入手できます。
http://www.hp.com/go/hpcaliper
次の HP DSPP (Developer & Solution Partner Program) Web サイトにも、HP-UX コンパイラ、HP Caliper、アプリケー
ションのパフォーマンスの調整など、関連トピックの多数のオンラインセミナを含む有用な情報があります。
http://www.hp.com/go/dspp
[1]
Ren-Cang Li, Peter Markstein, Jon P. Okada, James W. Thomas, 『The Libm Library and Floating Point
Arithmetic
in
HP-UX
for
Itanium-Based
Systems
』
http://h21007.www2.hp.com/dspp/files/unprotected/Itanium/FP_White_Paper_V3.pdf,2003 年
[2]
Peter Markstein, 『IA-64 and Elementary Functions, Speed and Precision 』 ,Hewlett-Packard Professional
Books, Prentice Hall, Inc., 2000 年
[3]
Pettis, K. , Hansen, R.C., 『Profile Guided Code Positioning』, Proceedings of the ACM SIGPLAN 1990
Conference on Programming Language Design and Implementation, SIGPLAN Notices, Vol 25, No. 6,
1990.年 6 月
[4]
R. Ju, K. Nomura, U. Mahadevan, L-C. Wu, 『 A Unified Compiler Framework for Control and Data
Speculation』, Proceedings of PACT '00, 2000 年 10 月, pp. 157-168
[5]
Robert Hundt, 『HP Caliper: A Framework for Performance Analysis Tools』, IEEE Concurrency Magazine,
Los Alamitos, CA 2000.年 10 – 12 月
[6]
U. Mahadevan, K. Normura, R. Ju, R. Hank, 『Applying Data Speculation in Modulo Scheduled Loops』,
Proceedings of PACT '00, 2000 年 10 月, pp. 169-178
[7]
Vugranam C. Sreedhar, Roy Dz-Ching Ju, David M. Gillies, Vatsa Santhanam, 『Translating Out of Static
Single Assignment Form』, Proceedings of the 6th International Symposium on Static Analysis 1999 年: pp.
194-210.
[8]
V. S. Sastry , Roy D. C. Ju, 『 A new algorithm for scalar register promotion based on SSA form 』 ,
Proceedings of the ACM SIGPLAN '98 Conference on Programming Language Design and Implementation
(PLDI), pages 15-25, Montreal, Canada, 17-19 June 1998. SIGPLAN Notices 33(5), 1998 年 5 月
[9]
David M. Gillies, Roy Dz-Ching Ju, Richard Johnson, Michael S. Schlansker, 『Global Predicate Analysis
and Its Application to Register Allocation』, Proceedings of MICRO 1996 年, pp. 114-125.
[10]
Itanium
Software
Conventions
and
Runtime
Architecture
http://h21007.www2.hp.com/dspp/files/unprotected/Itanium/swconv-01.pdf, 2001 年
[11]
[12]
『C++ ABI Summary』, http://www.codesourcery.com/cxx-abi, 2001年
Sungdo Moon, Xinliang D. Li, Robert Hundt, Dhruva Chakrabarti, Luis A. Lozano, Uma Srinivasan, ShinMing Liu, 『SYZYGY—A Framework for Scalable Cross-Module IPO』, International Symposium on Code
Generation and Optimization (CGO)、2004 年
[13]
Dhruva R. Chakrabarti, Luis A. Lozano, Xinliang D. Li, Robert Hundt, Shin-Ming Liu, 『 Scalable High
Performance Cross-Module Inlining』, International Conference on Parallel Architectures and Compilation
Techniques (PACT), 2004 年
[14]
J. Thomas,『Inlining of Mathematical Functions in HP-UX for Itanium(R) 2』, Proceedings of the 2003 CGO,
The International Symposium on Code Generation and Optimization, IEEE Computer Society, 2003 年
[15]
T.
Johnson,
N.
McIntosh,
R.
Hundt,
『 Optimizing
Itanium-Based
Applications 』 ,
http://h21007.www2.hp.com/dspp/files/unprotected/Itanium/OptimizingApps-ItaniumV4-1.pdf, 2004
年
[16]
『Performance Tuning with HP-UX Itanium® Compilers』 (Webcast),
http://h21007.www2.hp.com/dspp/ne/ne_EventDetail_IDX/1,,835!0!,00.html, 2004 年
Guide,
付録:非互換性のまとめ
この項では、AR1204 コンパイラと以前のリリースの間に存在する既知の非互換性についてまとめます。
旧形式 C++ ランタイムと標準 C++ ランタイム
HP では、HP-UX で動作する C++ アプリケーションに対して 「旧形式 C++ ランタイム」と「標準 C++ ランタイム」の 2 つ
の異なる実行時環境をサポートしています。「旧形式 C++ ランタイム」は、オリジナルの IOstream ライブラリ (C++ の
初期の実装で定義されており、cfront ベースの C++ コンパイラに元来含まれている) と Standard Template Library の
1995 年前後の初期のバージョンに基づいています。「標準 C++ ランタイム」は、1998 年末に発行された ISO/ANSI
C++ International Standard (ISO/IEC 14882:1998—http://www.ncits.org/cplusplus.htm) に含まれている C++ ラ
イブラリの最終定義に基づいています。
「 旧 形 式 」 と 「 標 準 」 、 両 方 の C++ ラ ン タ イ ム に は 、 Rogue Wave の tools.h++ ラ イ ブ ラ リ
(http://www.roguewave.com/products/enterprise/) が含まれています (tools.h++ 7.0.1 は「旧形式」 C++ ランタイ
ム、tools.h++ 7.1.1 は「標準」 C++ ランタイム)。
2 つの C++ ランタイムは、似てはいますが提供するインタフェースと機能は同じではありません。C++ 言語の最終的な
標準に合わせて、いくつかのインタフェース (API) の変更と、多数の新しいインタフェースの導入を行っています。「標準」
C++ランタイムは、「旧形式」 C++ ランタイムのスーパーセットではありません。したがって、互換性のないライブラリが
2 つ別々に存在する結果となります。このため、C++ アプリケーションはこれらのランタイム ライブラリの 1 つを選択し、
一貫していずれかの C++ ランタイムでコンパイルとリンクを実行する必要があります。
HP C++ コンパイラの、aCC では -AA オプションは標準 C++ ランタイムを選択し、-AP オプションは旧形式の C++ ラ
イブラリ (とランタイム) を選択します。PA-RISC プラットフォームでは、旧形式の C++ ランタイムがデフォルトであり、IPF
プラットフォームでは、標準 C++ ランタイムがデフォルトです。
旧形式 C++ ランタイムは、C++ の最終標準が開発され、公開されるまでに開発されてきた多数の C++ アプリケーショ
ンとの互換性を保つために提供されています。標準 C++ ランタイムは、移植性が高く、標準準拠のアプリケーションの
構築と実行に必要です。
詳細については、次を参照してください。
http://h21007.www2.hp.com/dspp/tech/
tech_TechSoftwareDetailPage_IDX/1,1703,1740,00.html
HP-UX Release B.11.22 での C コンパイラの変更点
HP-UX Release B.11.22 から方針が転換され、HP-C コンパイラは、旧バージョンの HP-C コンパイラとの完全なソース
互換性を提供しません。以前のバージョンと新しいバージョンの間の違いを一覧表で示します。
• 「-Ac」 (K&R) モードはサポートされません。
• 新しいバージョンでは、暗黙の「int」変数宣言をサポートしていません (つまり、「int x;」が単に「x;」と記述され
ているファイルは解釈できません)。
• +M0 と +M1 の移行オプションは無視されます。
• MPE long ポインタ (^) はサポートされません。
• HP_ALIGN プラグマ (MPE アラインメント) はサポートされません (代わりに「#pragma pack」または「#pragma
align」を使用)。
• +L (listing) オプションとそれに関連するリスト制御プラグマ (LINES、WIDTH、TITLE、SUBTITLE、PAGE、LIST
および AUTOPAGE) はサポートされません。
• 新しいコンパイラはプラグマ内のマクロを展開しません。
• スタンドアロン C ツールである lint、cb、cflow、cxref、endif、protogen はサポートされません。
• align および pack プラグマの動作が異なります。
HP-UX Release B.11.22 で修正された C++ の問題点
long double と __float80 データ型に対する マングリング コードは、HP-UX B.11.22 以前のコンパイラでは反転
されています。そのため、これらのデータ型を使用したコードにはバイナリでの互換性がありません。以前のコンパイラ
でコンパイルしたコードで、これらの型のいずれかまたは両方を使用している場合は、再コンパイルする必要があります。
以前のコンパイラでコンパイルされたコードと新しいコンパイラでコンパイルされたコードを混合した場合、名前マングリ
ングの曖昧性の欠陥により、不完全なシンボルが生成される可能性があります。リンク時に不完全なシンボルが報告さ
れた場合には、HP-UX B.11.22 以降のコンパイラを使用して、すべてのコードを再コンパイルする必要があります。
HP-UX Release B.11.22 より以前の、Itanium ベース システム用の C++ コンパイラでは、64 ビット モードのデフォルト
で誤ってビット フィールドを符号なしとして取り扱っていました。これは HP-UX B.11.22 で修正されています。この古い
動作に依存する 64 ビット アプリケーションでは、+ub オプションを使用すると、デフォルトで、引き続きビット フィールド
を符号なしとして取り扱うことができます。
お問い合わせはカスタマー インフォメーションセンターへ
03-6416-6660
月~金9:00~19:00 土10:00~18:00 (日、祝祭日、年末年始および5/1を除く)
HP-UX 製品に関する情報は http://www.hp.com/jp/hpux
HP-UX に関する技術情報は http://www.hp.com/jp/developer
Intel、インテル、Intel Inside ロゴ、Itanium は、米国におけるIntel Corporationまたはその子会社の
商標または登録商標です。
記載されている会社名および商品名は、各社の商標または登録商標です。
記載事項は2004年12月現在のものです。
本書に記載された内容は、予告なく変更されることがあります。
本書中の技術的あるいは校正上の誤り、省略に対して、
いかなる責任も負いかねますのでご了承ください。
本書は、『Compiler Technical Overview, HP and the Intel® Itanium® processor family (2005/1/10)』 (英語) をもとに日本語
で提供するものです。
© Copyright 2005 Hewlett-Packard Development Company,L.P.
日本ヒューレット・パッカード株式会社
〒140-8641 東京都品川区東品川2-2-24 天王洲セントラル
PDFHS04012-02
Fly UP