日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS
|
目次 | 索引 |
4.8.4 浮動小数点データ・タイプを使用するコード |
OpenVMS Alpha では,VAX 浮動小数点データ・タイプと IEEE 浮動小数点データ・タイプをハードウェアでサポートしています。 OpenVMS I64 では,IEEE 浮動小数点データ・タイプをハードウェアで,VAX 浮動小数点データ・タイプをソフトウェアでサポートしています。
ほとんどの OpenVMS I64 のコンパイラでは, VAX 浮動小数点データ・タイプを生成できるように, /FLOAT=D_FLOAT および /FLOAT=G_FLOAT 修飾子が用意されています。これらの修飾子を指定しないと, IEEE 浮動小数点データ・タイプが使用されます。
I64 BASIC コンパイラを使用してデフォルトの浮動小数点データ・タイプを指定するには,/REAL_SIZE 修飾子を使用します。指定できる値は,SINGLE (Ffloat),DOUBLE (Dfloat), GFLOAT,SFLOAT,TFLOAT,および XFLOAT です。
OpenVMS Alpha で IEEE 修飾子を指定してアプリケーションをコンパイルすると,Alpha で IEEE 浮動小数点の値を使用してアプリケーションの動作をテストできます。その結果,適切な結果が得られた場合は,同じ修飾子を使用して, I64 システムでアプリケーションをビルドすることができます。
VAX 浮動小数点形式を使用するオプションを指定した OpenVMS アプリケーションを I64 でコンパイルすると,コンパイラは浮動小数点形式を変換するコードを自動的に生成します。アプリケーションで一連の算術演算を実行すると,このコードは以下の処理を行います。
算術演算が実行されない場合 (VAX 浮動小数点データのフェッチの後にストア・インストラクションが続く場合) は,変換は行われません。このような状況は move 命令で処理されます。
VAX 形式と IEEE 形式には以下の相違点があるため,算術演算の結果が異なる場合が稀に発生します。
これらの違いにより,特定のアプリケーションでは問題が発生することがあります。
OpenVMS Alpha と OpenVMS I64 の浮動小数点データ・タイプの相違点,およびこれらの相違点がポーティング後のアプリケーションに与える影響の詳細については, 第 5 章 およびホワイトペーパー『Intel® Itanium® における OpenVMS 浮動小数点演算について』を参照してください。このホワイトペーパーが入手できる Web サイトについては,「まえがき」の「関連資料」の項を参照してください。
注意 浮動小数点に関する上記のホワイトペーパーが作成された後で, /IEEE_MODE のデフォルトが FAST から DENORM_RESULTS に変更されました。つまり,デフォルト設定で浮動小数点演算を実行した場合, VAX 形式の浮動小数点演算や /IEEE_MODE=FAST を使用したときに致命的な実行時エラーになっていたケースで, Infinity または Nan として出力される値が生成される場合があります (業界標準の動作)。また,値が非常に小さいために正規化によって表現できなくなると,ただちに 0 になるのではなく,結果がデノーマル範囲になることが認められるため,このモードでの非ゼロ最小値は,はるかに小さな値になります。このデフォルトは,プロセス起動時に I64 で設定されるデフォルトと同じです。 |
OpenVMS I64 に移植したコードで LIB$WAIT が使用されていると,予測外の結果が発生することがあります。以下に C の例を示します。
float wait_time = 2.0; lib$wait(&wait_time); |
OpenVMS I64 システムでは,このコードは S_FLOATING を LIB$WAIT に送ります。しかし,LIB$WAIT は F_FLOATING を想定しているため,FLTINV 例外を返します。
LIB$WAIT には 3 つの引数を指定することができます。 LIB$WAIT で 3 つの引数を使用して上記のコードを書き直すと,I64 システムと Alpha システムの両方で正常に動作するコードを作成できます。以下の変更後のコードは,/FLOAT 修飾子を指定せずにコンパイルすると,正常に動作します。
#ifdef __ia64 int float_type = 4; /* use S_FLOAT for I64 */ #else int float_type = 0; /* use F_FLOAT for Alpha */ #endif float wait_time = 2.0; lib$wait(&wait_time,0,&float_type); |
よりよいコーディング手法として,アプリケーションで (SYS$STARLET_C.TLB から) LIBWAITDEF をインクルードし,浮動小数点データ・タイプの名前を指定する方法があります。このようにして作成したコードは,保守がより容易になります。
LIBWAITDEF は以下のシンボルをインクルードします。
以下の例では,コードに libwaitdef.hをインクルードし,浮動小数点データ・タイプの名前を指定する方法を示しています。この例でも,プログラムのコンパイル時に /FLOAT が指定されないことを前提にしています。
#include <libwaitdef.h> . . . #ifdef __ia64 int float_type = LIB$K_IEEE_S; /* use S_FLOAT for IPF */ #else int float_type = LIB$K_VAX_F; /* use F_FLOAT for Alpha */ #endif float wait_time = 2.0; lib$wait(&wait_time,0,&float_type); |
OpenVMS I64 へ移植するコードに正しくないコマンド・テーブル宣言があると,予想外の結果となる場合があります。一例として,以下のようなエラーがあります。アプリケーションでは,CLD ファイルからオブジェクト・モジュールを作成するのにコマンド定義ユーティリティが使用されます。このアプリケーションは CLI$DCL_PARSE を呼び出し,コマンド行を解析します。 CLI$DCL_PARSE は次のようなエラーで失敗する場合があります。
%CLI-E-INVTAB, command tables have invalid format - see documentation |
このコードは,コマンド・テーブルが外部データ・オブジェクトとして定義されるように修正する必要があります。
たとえば,VAX あるいは Alpha アプリケーションの BLISS モジュールで,コマンド・テーブル (DFSCP_CLD) が次のように間違って宣言されていたとします。
EXTERNAL ROUTINE DFSCP_CLD |
これは次のように変更すべきです。
EXTERNAL DFSCP_CLD |
FORTRAN のモジュールで次のような宣言があったとします。
EXTERNAL DFSCP_CLD |
これは次のように変更すべきです。
INTEGER DFSCP_CLD CDEC$ ATTRIBUTES EXTERN :: DFSCP_CLD |
同様に,C 言語で作成されたアプリケーションで次のようなコマンド・テーブルが定義されていたとします。
int jams_master_cmd(); |
このコードは,次のように外部参照に変更すべきです。
extern void* jams_master_cmd; |
正しい宣言に変更すると,VAX,Alpha,および I64 のすべてのプラットフォームで動作するようになります。
OpenVMS I64 では,これまでに OpenVMS でサポートされたすべてのスレッド・インタフェースがサポートされます。スレッドを使用する大部分の OpenVMS Alpha コードは,まったく変更なしで OpenVMS I64 へのポーティングが可能です。ここでは,その例外について説明します。スレッドを使用するコードのポーティングで発生する最大の問題は,スタック領域の使用です。 I64 のコードは,対応する Alpha のコードよりはるかに多くのスタック領域を使用します。このため,スレッド化されたプログラムが Alpha で問題なく動作していても,I64 ではスタック・オーバーフローが発生することがあります。
オーバーフローの問題を軽減するために,OpenVMS I64 ではデフォルトのスタック・サイズが拡大されています。しかし,アプリケーションで特定のスタック・サイズを要求する場合,そのデフォルトの変更は機能しないため,より大きなスタックを要求するようにアプリケーションのソース・コードを変更しなければなりません。そのような場合は,まず,8 KB ページを 3 つ (24576 バイト) 追加してみることをお勧めします。
必要なスタック・サイズを拡大した結果,もう 1 つの副作用として P0 空間に対する要求が拡大します。スレッド・スタックは P0 ヒープから割り当てられます。スタックが大きくなると,プロセスのメモリ・クォータを超過してしまう可能性があります。極端な場合,P0 空間が完全に満杯になり,プロセスで同時に使用されるスレッドの数を削減しなければならなくなることもあります (またはその他の変更を行って,P0 メモリに対する要求を削減する場合もあります)。
『HP OpenVMS Version 8.2 リリース・ノート [翻訳版]』を参照して, OpenVMS でスレッドのサポートに関して行われた最新の機能向上について十分理解しておくことをお勧めします。 POSIX Threads C 言語ヘッダ・ファイル PTHREAD_EXCEPTION.H で 1 つの変更が行われたため,以前の動作に依存しているアプリケーションのポーティングを行うと,問題が発生します。
OpenVMS I64 8.2 では, DCL の THREADCP コマンドはサポートされません。 OpenVMS I64 では,スレッド関係のイメージ・ヘッダ・フラグの状態のチェックおよび修正には, OpenVMS Alpha の THREADCP コマンドの代わりに, DCL コマンド SET IMAGE および SHOW IMAGE が使用できます。詳細は『OpenVMS DCL ディクショナリ』を参照してください。
THREADCP コマンドについては『Guide to the POSIX Threads Library』で説明しています。
スレッド関係のイメージ・フラグの設定を変更したい場合は,次のように新しいコマンド SET IMAGE を使用する必要があります。
4.8.6 スレッドを使用するコード
$ SET IMAGE/FLAGS=(MKTHREADS,UPCALLS) FIRST.EXE |
2 つの既存のスレッド API ライブラリ・ルーチン cma_delay と cma_time_get_expiration は, VAX F FLOAT 形式を使用する浮動小数点形式のパラメータを受け付けます。これらのルーチンを呼び出すアプリケーション・モジュールは, /FLOAT=D_FLOAT または /FLOAT=G_FLOAT 修飾子を指定してコンパイルし,VAX F FLOAT がサポートされるようにしなければなりません (ただし,アプリケーションで倍精度バイナリ・データも使用している場合は,/FLOAT=G_FLOAT 修飾子を指定する必要があります)。浮動小数点のサポートの詳細については,コンパイラのドキュメントを参照してください。
cma_delay あるいは cma_time_get_expiration のいずれかを使用する C 言語モジュールが, IEEE 浮動小数点モードで間違ってコンパイルされると,次のようなコンパイラの警告メッセージが表示されます。
4.8.6.1 スレッド・ルーチン cma_delay および cma_time_get_expiration
cma_delay ( ^ %CC-W-LONGEXTERN, The external identifier name exceeds 31 characters; truncated to "CMA_DELAY_NEEDS_VAX_FLOAT______". |
このような警告メッセージの原因となるようなオブジェクト・ファイルがリンクされている場合,リンカはこのシンボルから未定義シンボル・メッセージを表示します (リンカが生成したイメージをこのあと実行すると,ルーチンの呼び出しで ACCVIO とともにフェールします)。
注意 これらのルーチンについては,ユーザ向けのドキュメントには記載されていませんが,既存のアプリケーションで使用できるよう,サポートが継続されます。 |
4.8.7 自然な境界に配置されていないデータを含むコード |
データ参照のパフォーマンスを最適なレベルに向上させるには,データを自然な境界に配置することをお勧めします。データが自然な境界に配置されていない場合,OpenVMS Alpha でも OpenVMS I64 でもパフォーマンスが大幅に低下します。
アドレスが,バイト数で表したデータ・サイズの整数倍になっている場合,そのデータは自然な境界に配置されています。たとえば,ロングワードは,4 の倍数のアドレスで自然な境界に配置され,クォドワードは 8 の倍数のアドレスで自然な境界に配置されます。構造体のすべてのメンバが自然な境界に配置されると,その構造体も自然なアラインメントになります。
自然な境界に配置できない場合もあるので, OpenVMS I64 システムでは,自然な境界に配置されていないデータを参照することによる影響を管理するための支援機能を提供しています。 Alpha と I64 のコンパイラは,発生する可能性のある大部分のアラインメントの問題を自動的に修正し,修正できない問題にはフラグを付けます。
自然な境界に配置されていない共有データがあると,パフォーマンスが低下するだけでなく,プログラムが正常に実行されない原因にもなります。したがって,共有データは自然な自然な境界に配置する必要があります。 1 つのプロセスの中にあるスレッドの間,プロセスと AST の間,複数のプロセスで使われるグローバル・セクションにおいてデータは共有されます。
自然な境界に配置されていないデータのインスタンスを検出するには, 自然な境界に配置されていないデータへの参照をコンパイラがコンパイル時に報告する修飾子を使用します。この修飾子は I64 のほとんどのコンパイラで提供されています。
コンパイラ | スイッチ |
---|---|
BLISS | /CHECK=ALIGNMENT |
C | /WARN=ENABLE=ALIGNMENT |
Fortran | /WARNING=ALIGNMENT |
HP Pascal | /USAGE=PERFORMANCE |
自然な境界に配置されていないデータを実行時に検出する OpenVMS デバッガの修飾子など,他の支援機能は,将来のリリースで計画されています。
以下の 1 つ以上の方法を使用すると,自然な境界に配置されていないデータに関する問題を回避することができます。
注意 自然な境界に配置するように変換されたソフトウェアは,同じ OpenVMS Cluster 環境内や,ネットワークを介して動作している他の変換されたソフトウェアとの間で,互換性の問題を起こすことがあります。次の例を参照してください。
このような場合は,アプリケーションのすべての部分が,同じタイプのデータ,つまり,自然な境界に配置されたデータか自然な境界に配置されていないデータのどちらか一方を想定するように変更する必要があります。 |
4.8.8 OpenVMS Alpha の呼び出し規則に依存するコード |
OpenVMS Alpha の呼び出し規則に明示的に依存するアプリケーションは,変更が必要になる可能性があります。 OpenVMS I64 の呼び出し規則は,Intel の呼び出し規則をベースにしており,部分的に OpenVMS 固有の変更が加えられています。 OpenVMS I64 の呼び出し規則で導入された大きな相違点は次のとおりです。
詳細については, 第 2 章 を参照してください。
ここでは,確認が必要で,場合によっては変更も必要な特権コードについて説明します。
4.8.9 特権コード
目次 | 索引 |
|