HP OpenVMS Systems Documentation |
| 前へ | 次へ | 目次 | 索引 |
I64 システムでは,HP C Version 7.1 がサポートされます。ポーティングに関する注意事項については,HP C のリリース・ノートを参照してください。
6.6.1 I64 浮動小数点のデフォルト
Alpha のネイティブ・コンパイラのデフォルトは /FLOAT=G_FLOAT です。 I64 のデフォルトは /FLOAT=IEEE_FLOAT/IEEE=DENORM です。
OpenVMS I64 では,IEEE 以外の浮動小数点表現はハードウェアでサポートされません。 VAX 浮動小数点形式は,算術演算を実行する前に IEEE 形式に変換し,結果を適切な VAX 形式に戻す実行時コードを生成することで,コンパイラでサポートされています。このため,実行時のオーバヘッドが増加し, Alpha (および VAX) のハードウェアで同じ演算を実行する場合と比較すると,精度が少し低下します。ソフトウェアでの VAX 形式のサポートは,ディスクに格納されているバイナリ形式の浮動小数点データを取り扱う必要のある特定のアプリケーションで,互換性を維持するための重要な機能ですが,この機能の利用はお勧めできません。この変更は,デフォルトが VAX の /FLOAT=D_FLOAT から Alpha の /FLOAT=G_FLOAT に変更されたのに類似しています。
また,/IEEE_MODE のデフォルトは,OpenVMS Alpha では FAST でしたが,OpenVMS I64 では DENORM_RESULTS に変更されています。つまり,VAX 浮動小数点形式や /IEEE_MODE=FAST を使用すると致命的な実行時エラーが発生していた浮動小数点演算で,デフォルトにより,Inf または Nan として出力される値が生成されるようになりました (業界標準の動作)。また,このモードでの非ゼロ最小値は以前よりはるかに小さくなります。これは,値が非常に小さくなって正規化した状態では表現できなくなったときに,結果がデノーマル範囲にあることが許されるからで,ただちに 0 になることはありません。
6.6.2 /IEEE_MODE 修飾子のセマンティック
OpenVMS Alpha では,/IEEE_MODE 修飾子は一般に,コンパイルで生成されるコードに対して最大の影響を与えます。異なる /IEEE_MODE 修飾子を使用してコンパイルされた関数の間で呼び出しを行うと,各関数の動作は,それがコンパイルされたときのモードに従います。
OpenVMS I64 では,/IEEE_MODE 修飾子は基本的にプログラム起動時のハードウェア・レジスタの設定にだけ影響します。一般に,各関数に対する /IEEE_MODE の動作は,メイン・プログラムのコンパイル時に指定された /IEEE_MODE オプションによって制御されます。コンパイラは,各コンパイルでできるオブジェクト・モジュールを,コンパイル時の修飾子で指定された浮動小数点制御でマークします。 I64 リンカが実行イメージを作成する際,イメージの main エントリ・ポイントへの転送アドレスを提供したオブジェクト・モジュールから浮動小数点制御をそのイメージ自体へコピーします。この処理は,そのイメージに対するホール・プログラム浮動小数点モード (whole program floating-point mode) と呼ばれます。この後,実行のためにイメージを起動すると,このホール・プログラム浮動小数点モードに従ってハードウェアの浮動小数点制御が初期化されます。実行時に特定の制御設定が必要となるようなコードのセクションから制御が移る場合に,ホール・プログラム浮動小数点モードの設定がリストアされるよう,実行時に浮動小数点制御を修正するようなコードを作成してください。
/IEEE_MODE 修飾子がメイン・プログラムを含まないコンパイルに適用される場合も,この修飾子には効果があります。浮動小数点定数式の評価に影響を与え,そのコンパイルからの呼び出しに対して,算術演算ライブラリで使用される EXCEPTION_MODE を設定します。
/IEEE_MODE 修飾子は,そのコンパイルでインライン・コードとして生成された浮動小数点演算の例外動作には影響を与えません。したがって,浮動小数点例外動作がアプリケーションにとって重要な場合は,メイン・プログラムを含むコンパイルも含めて,すべてのコンパイルで /FLOAT および /IEEE_MODE を同じ設定にする必要があります。
Alpha でも,/IEEE_MODE=UNDERFLOW_TO_ZERO に設定するには,実行時状態レジスタを設定する必要があります。したがって,この設定を他のコンパイルでも有効にするには,メイン・プログラムを含むコンパイルでこの設定を指定する必要があります。
最後に,/ROUNDING_MODE 修飾子は /IEEE_MODE と同じように影響を与え,ホール・プログラム浮動小数点モードに含まれ,また,VAX 浮動小数点演算は実際には IEEE インストラクションで実行されるため, VAX 形式の浮動小数点を使用するコンパイルは /IEEE_MODE=DENORM/ROUND=NEAREST でコンパイルした場合と同じホール・プログラム浮動小数点モード設定で動作することに注意してください。
6.6.3 定義済みマクロ
I64 コンパイラでは,Alpha のネイティブ・コンパイラと同じ意味を持つ多くのマクロがあらかじめ定義されていますが, Alpha アーキテクチャを指定するマクロは定義されていません。その代わりに, __ia64マクロと __ia64__マクロが,I64 向けの Intel および gcc コンパイラと同じ手法で定義されています。 G_FLOAT から IEEE への浮動小数点表現の変更は,定義済みマクロでもデフォルトで反映されています。
一部のユーザは,
__ALPHAマクロが定義されていない場合,ターゲットは VAX システムでなければならないという前提で書かれた条件付きソース・コードを簡単に取り扱う方法として, /DEFINE を使用するか,またはヘッダ・ファイルに記述して,明示的に
__ALPHAマクロを定義しようとしました。しかし,このような定義を行うと,CTRL ヘッダおよびその他の OpenVMS ヘッダは I64 に対して誤ったパスを選択します。このコンパイラを使用する場合,Alpha アーキテクチャの定義済みマクロを定義すべきではありません。
6.7 HP C++
OpenVMS I64 では,HP C++ Version 7.1 がサポートされます。ポーティングに関する注意事項については, HP C++ のドキュメントも参照してください。
6.7.1 浮動小数点と定義済みマクロ
C コンパイラの浮動小数点のデフォルト,/IEEE_MODE セマンティック,定義済みマクロに関する注意事項が, C++ コンパイラにもそのまま適用されます。
6.7.2 long double
long double タイプは常に 128 ビット IEEE 4 倍精度で表現されます。 /L_DOUBLE_SIZE=64 修飾子は無視され,警告メッセージが表示されます。 Alpha では C++ ライブラリの 64 ビット long double のサポートに制限がありました。64 ビット浮動小数点タイプが必要なコードでは, long double の代わりに double を使用していました。
6.7.3 オブジェクト・モデル
I64 の C++ コンパイラが使用するオブジェクト・モデルと名前マングリング・スキーマは,Alpha の場合と大きく異なります。 ARM オブジェクト・モデルは使用できません。使用できるのは,ANSI/ISO C++ 標準をサポートするオブジェクト・モデルのみです。ただしこれは,Alpha で実装されている /MODEL=ANSI オブジェクト・モデルとも異なり,I64 のモデルは業界標準の I64 ABI の実装となっています。 C++ オブジェクトの配置 (非 POD データ),あるいは .obj ファイルにエンコードされた外部マングル名に依存するプログラムは,作成し直す必要があります。このようなプログラムは,本質的に実装に大きく依存します。しかし,実装に依存しない適切な方法で標準の C++ 機能を使用するプログラムであれば,ポーティングは難しくありません。
6.7.4 言語ダイアレクト
cfront ダイアレクトはサポートされません (Alpha 版からも削除されます)。 /standard=cfront を使用してコンパイルした場合は, relaxed_ansi ダイアレクトが使用されます。
6.7.5 テンプレート
OpenVMS I64 では,.OBJ ファイルは EOBJ ではなく ELF 形式で実装されます。また I64 リンカと連動し, C++ テンプレートおよびインライン関数を使用した場合に発生するリンク時の重複定義の問題を解決するために Windows および UNIX プラットフォームの両方でよく使用される COMDAT セクションの概念をサポートします。 Alpha では,リンカに単一の定義インスタンスを提示するリポジトリ・メカニズムによってこれらの問題を処理します。 I64 ではこの処理にリポジトリ・メカニズムは必要なく,リンカが自動的に重複を解消します。このため,Alpha でサポートされるリポジトリ・ベースのテンプレート・インスタンス化オプションは, IPF ではサポートされません。リポジトリでオブジェクトを処理しようとする Alpha ビルド・プロシージャは I64 では使えないので,変更が必要になります (I64 ではリポジトリにはオブジェクトがなく,デマングラ・データベースです)。ほとんどの場合,コンパイラの COMDAT インスタンス化の使用により,ビルド・プロシージャでリポジトリを直接扱う必要はなくなります。
6.8 Java
OpenVMS I64 では,Javatm Version 1.4.2-1 がサポートされます。 OpenVMS Alpha の Java と OpenVMS I64 の Java の間に相違点はありません。
6.9 MACRO-32
OpenVMS Alpha でコンパイルされた大部分の VAX MACRO プログラムは,まったく変更せずに OpenVMS I64 で再コンパイルできます。しかし,非標準戻り値を返すルーチンを呼び出すプログラムや,JSB インストラクションを使用して,他の言語で作成されたルーチンを呼び出すプログラムでは,ソース・ファイルに新しいディレクティブを追加する必要があります。詳細については,『OpenVMS MACRO-32 Porting and User's Guide』を参照してください。
6.10 HP Pascal
Alpha と I64 の両方で HP Pascal Version 5.9 が利用できます。
OpenVMS Alpha 上の Pascal と OpenVMS I64 上の Pascal では,明らかになっている言語上の違いはありません。唯一の違いは,HP のほかの I64 コンパイラと同様に,浮動小数点のデフォルト・データ・タイプが VAX 形式ではなく IEEE 形式である点です。
6.10.1 /ARCH および /OPTIMIZE=TUNE 修飾子
「コンパイル・アンド・ゴー」の互換性を維持するために, /ARCH および /OPTIMIZE=TUNE 修飾子に対する Alpha 固有のキーワードがコンパイラ起動コマンドで受け付けられます。これらの値が無視されることを示す情報メッセージが出力されます。
/ARCH および /OPTIMIZE=TUNE 修飾子に対する I64 固有のキーワードは,OpenVMS I64 コンパイラで定義されていますが,これは開発用に提供されるものです。これらの修飾子の動作は予測できないため,使用すべきではありません。
この章では,ポーティングに関するその他の検討事項について説明します。
7.1 ハードウェアに関する検討事項
ここでは,Alpha,PA-RISC,および Itanium プロセッサ・ファミリに関して説明します。また,プロセッサに関連する開発上の問題点について説明し, C 言語とアセンブリ言語の両方を使用して,典型的なプロセッサ依存コードの例を示します。
7.1.1 Intel Itanium プロセッサ・ファミリの概要
Itanium アーキテクチャは,エンジニアリング・ワークステーションおよび e コマース・サーバ向けの 64 ビット・プロセッサとして, HP と Intel が開発しました。 Itanium プロセッサ・ファミリでは, EPIC (Explicitly Parallel Instruction Computing) という新しいアーキテクチャが採用されています。
EPIC の設計では,最も重要な目標として,インストラクション・レベルの並列処理,ソフトウェア・パイプライン化,スペキュレーション,プレディケーション,大きなレジスタ・ファイルなどが設定されました。これらの機能を実現することで,Itanium プロセッサは複数のインストラクションを同時に実行できます。 EPIC は,これらの並列機能の多くの制御をコンパイラに委ねます (したがって,名前に "Explicitly" (明示的) という言葉が盛り込まれています)。この結果,コンパイラは複雑になりますが,これらの機能をコンパイラで直接利用することが可能になります。
EPIC は将来の世代のプロセッサがさまざまなレベルの並列処理を利用できるように設計されています。将来の拡張性が考慮されており,コンパイラが生成するマシン・コードについては, (並列に実行可能な) 1 つのグループ内の命令数には制限がありません。
Intel Itanium プロセッサ・ファミリ向けのアセンブリ・プログラミングの詳細については,『Intel® Itanium® Architecture Assembly Language Reference Guide』を参照してください。以下の Web サイトで提供されています。
http://developer.intel.com/software/products/opensource/tools1/tol_whte2.htm |
Alpha は 64 ビットのロード/ストア RISC アーキテクチャであり,パフォーマンスに最も影響を与える 3 つの要素に特に重点を置いて設計されています。 3 つの要素とは,クロック速度,複数のインストラクションの発行,および複数のプロセッサです。
Alpha の設計者たちは,最新の理論上の RISC アーキテクチャ設計要素を調査,分析し,ハイパフォーマンスな Alpha アーキテクチャを開発しました。
Alpha アーキテクチャは,特定のオペレーティング・システムやプログラミング言語に偏らないように設計されています。 Alpha ではオペレーティング・システムとして OpenVMS Alpha,Tru64 UNIX,および Linux がサポートされ,これらのオペレーティング・システムで動作するアプリケーションに対して簡単なソフトウェア移行がサポートされています。
Alpha は 64 ビット・アーキテクチャとして設計されました。すべてのレジスタのサイズが 64 ビットであり,すべての操作が 64 ビット・レジスタ間で実行されます。当初は 32 ビット・アーキテクチャとして開発され,後で 64 ビットに拡張されたのではありません。
インストラクションは非常に単純です。すべてのインストラクションが 32 ビットです。メモリ操作はロードとストアのいずれかです。すべてのデータ操作がレジスタ間で行われます。
Alpha アーキテクチャには特殊なレジスタや条件コードがないため,同じ操作の複数のインスタンスをパイプライン化するのは簡単です。
レジスタまたはメモリに書き込む 1 つの命令と,同じ場所から読み取りを行う別の命令とは相互に調整をします。このため,同時に複数の命令を実行する CPU の実装が簡単にできます。
Alpha では,複数のインプリメンテーション間でバイナリ・レベルの互換性を容易に維持でき,複数インストラクション発行のインプリメンテーションで完全な速度を簡単に維持できます。たとえば,インプリメンテーション固有のパイプライン・タイミングによる危険性,ロードディレイ・スロット,および分岐ディレイ・スロットはありません。
Alpha アーキテクチャでは,LDBU インストラクションと STB インストラクションを使用して,レジスタおよびメモリ間でバイトの読み書きを行います (Alpha では,LDWU および STW インストラクションによるワード読み書きもサポートされます)。バイト・シフトとマスキングは,通常の 64 ビット・レジスタ間インストラクションによって実行されます (インストラクション・シーケンスが長くならないように工夫されています)。
第 2 のプロセッサ (I/O デバイスを含む) から見ると, 1 つのプロセッサが発行した一連の読み取りと書き込みは,インプリメンテーションによって任意の順序に変更される可能性があります。このため,インプリメンテーションではマルチバンク・キャッシュ,バイパスされた書き込みバッファ,書き込みマージ,エラー発生時にリトライするパイプライン書き込みなどを使用できます。 2 つのアクセスの順序を厳密に維持しなければならない場合は,プログラムにメモリ・バリア命令を明示的に挿入できます。
基本的なマルチプロセッサ・インターロック機構は RISC スタイルの load_locked,modify, store_conditional シーケンスです。割り込みや例外,あるいは別のプロセッサからの妨害的な書き込みが発生せずに,シーケンスが実行されると,条件付きストアは正常終了します。割り込みや例外などが発生すると,ストア操作は失敗し,プログラムは最終的に元に戻って,シーケンスをリトライしなければなりません。このスタイルのインターロックは非常に高速のキャッシュにも対応できるため,複数のプロセッサが搭載されたシステムを構築するためのアーキテクチャとして, Alpha を特に魅力的なものにしています。
PALcode (privileged architecture library) は,特定の Alpha オペレーティング・システム・インプリメンテーションに固有のサブルーチンの集合です。これらのサブルーチンは,コンテキスト・スイッチング,割り込み,例外,およびメモリ管理のためのオペレーティング・システム・プリミティブを提供します。 PALcode は,パーソナル・コンピュータで提供される BIOS ライブラリのようなものです。
詳細については,『Alpha Architecture Handbook』(注文番号 EC-QD2KC-TE) を参照してください。
7.2 エンディアンに関する検討事項
OpenVMS Alpha または OpenVMS VAX から OpenVMS I64 へのポーティングを行う場合,エンディアンに関する問題について考慮する必要はありません。どのプラットフォームでも,OpenVMS はデータの格納と操作でリトル・エンディアンを使用します。この章では,エンディアンが異なるハードウェア・アーキテクチャ間でポーティングを行う際に,一般に考慮しなければならない問題点について,わかりやすく説明しています。
エンディアンとは,データがストアされる方法のことであり,マルチバイト・データ・タイプで各バイトを配置する方法を定義します。エンディアンが重要なのは,データを書き込んだマシンと異なるエンディアンのマシンでバイナリ・データを読み込もうとすると,異なる結果になるからです。データベースをエンディアンの異なるアーキテクチャに移動しなければならない場合には,このことが特に重要な問題になります。
エンディアンには,ビッグ・エンディアン (順方向バイト順,つまり MSF (most significant first)) とリトル・エンディアン (逆方向バイト順,つまり LSF (least significant first)) の 2 種類があります。エンディアンについて考える場合は,「big end in」と「little end in」という覚え方をすると便利です。 図 7-1 と 図 7-2 は, 2 つのバイト順方式を比較しています。
図 7-1 ビッグ・エンディアン・バイト順
図 7-2 リトル・エンディアン・バイト順
Alpha マイクロプロセッサでは OpenVMS や Tru64 UNIX などのオペレーティング・システムでリトル・エンディアン環境を提供し, PA-RISC マイクロプロセッサでは HP-UX オペレーティング・システムでビッグ・エンディアン環境を提供しています。
OpenVMS などのリトル・エンディアン・オペレーティング・システムでは,リトル・エンド,つまり,最下位有効バイトが最下位アドレスに格納されます。たとえば,0x1234 という 16 進数は 0x34 0x12 としてメモリに格納されます。 4 バイト値の場合も同様です。たとえば,0x12345678 は 0x78 0x56 0x34 0x12 として格納されます。ビッグ・エンディアン・オペレーティング・システムではこれとは逆の順に格納されます。たとえば,0x1234 は 0x12 0x34 としてメモリに格納されます。
4 バイト整数として格納されている 1025 (2 の 10 乗 + 1) という数値について考えてみましょう。メモリでは,この数値は以下のように表現されます。
リトル・エンディアン: 00000000 00000000 00000100 00000001 ビッグ・エンディアン: 00000001 00000100 00000000 00000000 |
Intel Itanium プロセッサ・ファミリ・アーキテクチャでは,ビッグ・エンディアンとリトル・エンディアンの両方のメモリ・アドレッシングがサポートされます。 Itanium プロセッサで動作する OpenVMS I64 と OpenVMS Alpha の間には,データの読み込みおよびデータ交換に関する問題はありません。 Alpha または I64 システム上の OpenVMS と, PA-RISC または Itanium プロセッサ・ファミリの HP-UX の間でデータを交換する必要がある場合は,バイトの入れ換えが必要になることがあります。
| 前へ | 次へ | 目次 | 索引 |