日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトルページ
目次
まえがき
第 1 部 : 概念と方法
第 1 章:Macro-32コードの移植の準備
第 2 章:MACROコンパイラのプラットフォームごとの動作
第 3 章:ソースに対する推奨される変更と必要な変更
第 4 章:移植したコードの性能改善
第 5 章:MACROの64ビット・アドレッシングのサポート
第 2 部:リファレンス・セクション
付録 A :MACROコンパイラの修飾子
付録 B :専用の指示文
付録 C :MACROコンパイラ・ビルトイン
付録 D :VAXからAlphaまたはI64への移植用のマクロ
付録 E :64ビット・アドレッシング用のマクロ
索引
PDF
OpenVMS ホーム
HP OpenVMS MACRO コンパイラポーティングおよびユーザーズ・ガイド

HP OpenVMS MACRO コンパイラ
ポーティングおよびユーザーズ・ガイド


目次 索引

OpenVMS Alpha システムまたは OpenVMS I64 システムにアプリケーションを移植する際に,書き込み可能なグローバル・セクションにある共用データを複数のプロセスが変更する場合は,アプリケーションがシングル・プロセッサ上でのみ動作する場合であっても,特に注意してください。また,メインライン・プロセス・ルーチンが変更するプロセス空間のデータが,非同期システム・トラップ (AST) ルーチンや条件ハンドラでも変更される可能性がある場合は,アプリケーションを調べる必要があります。 Alpha システムにおける読み取り-変更-書き込み操作に関するプログラミング上の問題についての詳細は, Migrating to an OpenVMS AXP System: Recompiling and Relinking Applications 1を参照してください。

  警告
不可分性を維持するときに,コンパイラは,Alpha PALcode の非アライン障害ハンドラで扱うことのできない,アラインされたメモリ命令を生成します。この命令では,アラインされていないアドレスに対して,回復不能な予約オペランド・フォルトが発生します。そのため,.PRESERVE ATOMICITY が指定されたすべてのメモリ参照は,アドレスがアラインされている必要があります ( 第 2.11.5 項 を参照)。



Alpha 上で VAX MACRO のバイト,ワード,またはアラインされていないロングワードに対するメモリ書き込み命令の細分性を維持するということは,指定されたデータに対して命令が正常に実行され,周囲のデータの一貫性が維持されることを保証するということを意味します。

VAX アーキテクチャには,メモリ内のバイト,ワード,アラインされていないロングワードに対して独立にアクセスする命令があるため,アラインされた同じロングワードの異なるバイトに 2 つのプロセスが同時に書き込んでも,互いに干渉が起こりません。

Alpha アーキテクチャのオリジナルの実装では,アラインされたロングワードおよびクォドワード・オペランドのみをアドレス指定できる命令が定義されていました。ただし,バイトとワードのオペランドのロードと格納が後で追加されました。

Alpha では,長さがロングワード未満のメモリや,アラインされていないメモリにデータ・フィールドを書き込むコードは,クォドワードのロード,変更したデータのクォドワードへの挿入,クォドワードの格納を行う割り込み可能な命令シーケンスを使用する必要があります。この場合,同じクォドワード内の異なるバイトに書き込もうとしている 2 つのプロセスは,実際にはクォドワード全体をロードし,演算を行い,保存します。ロード操作と格納操作のタイミングによっては,どちらかのバイト書き込みが失われる可能性があります。

Itanium アーキテクチャでは,バイト,ワード,ロングワード,クォドワードのアドレス指定が可能なため,アクセスの細分性が簡単に確保でき,オプションや宣言も必要ありません。

コンパイラには,バイト,ワード,アラインされていないロングワードの書き込みの一貫性を保証する /PRESERVE=GRANULARITY オプションがあります。 /PRESERVE=GRANULARITY オプションを指定すると,バイト,ワード,アラインされていないロングワードへの書き込みを行うすべての VAX 命令に対して,細分性が保たれる Alpha 命令が生成されます。また,必要に応じて VAX MACRO ソース・コードのセクションに .PRESERVE GRANULARITY 指示文と .NOPRESERVE GRANULARITY 指示文を挿入し,細分性の維持を有効または無効にすることもできます。

たとえば,命令 MOVB R1, (R2) は,次の Alpha コード・シーケンスを生成します。

LDQ_U     R23, (R2) 
INSBL     R1, R2, R22 
MSKBL     R23, R2, R23 
BIS       R23, R22, R23 
STQ_U     R23, (R2) 

LDQ_U 命令と STQ_U 命令の間で,他のコード・スレッドが (R2) が指すデータの一部を変更した場合,そのデータは上書きされて失われます。

次の Itanium コード・シーケンスが生成されます。

st1     [r28] = r9 

コマンド修飾子または指示文で,同じ命令に対して細分性を維持するように指定した場合, Alpha コード・シーケンスは次のようになります。

          BIC       R2,#^B0111,R24 
RETRY:    LDQ_L     R28,(R24) 
          MSKBL     R28,R2,R28 
          INSBL     R1,R2,R25 
          BIS       R25,R28,R25 
          STQ_C     R25,(R24) 
          BEQ       R25, FAIL 
           . 
           . 
           . 
FAIL:     BR        RETRY 

この場合,(R2) が指すデータが別のコード・スレッドによって変更されると,操作はリトライされます。

Itanium では,コードはすでに影響のあるメモリ位置にだけ書き込むようになっているため,コード・シーケンスは変わりません。

MOVW R1,(R2) 命令で,細分性を維持するために生成される Alpha コードは,コンパイラのレジスタ・アラインメント・トラッキング機能によって,レジスタ R2 が現在アラインされていると見なされているかどうかに依存します。 R2 がアラインされていると見なされている場合は,コンパイラは基本的に上の MOVB の例と同じコードを生成します。ただし, INSBL 命令と MSKBL 命令の代わりに INSWL 命令と MSKWL 命令が使用され, R2 のアドレスに対する BIC で #^B0110 を使用します。 R2 がアラインされていないと見なされている場合は,ワードが仮にクォドワード境界にまたがっている場合でも正しく書き込まれるように,コンパイラは 2 つの個別の LDQ_L/STQ_C ペアを生成します。

同様に Itanium でも,アドレスがワードにアラインされている場合は,コンパイラは単に st2 [r28] = r9を生成します。

  注意
細分性の維持が有効になっている場合,アラインされたワードを書き込むために生成されるコードでは,アドレスがアラインされていないと,実行時に回復不可能な予約オペランド・フォルトが発生します。書き込み先のアドレスがアラインされていない可能性がある場合は,アラインされていないワードに書き込むことができるコードを生成するようにコンパイラに指示します。それには,書き込み命令の直前で,コンパイラ指示文 .SET_REGISTERS UNALIGNED=Rn を使用します。

MOVL R1,(R2) 命令の細分性を維持するために,書き込み先のアドレスがアラインされていないと想定される場合でも,コンパイラは常に STL 命令を使用してロングワード全体を書き込みます。アドレスがアラインされていないと, STL 命令は非アライン・メモリ参照のフォルトになります。 PALcode の非アライン・フォルトのハンドラは,アラインされていないロングワードに書き込むために必要な,ロード,マスク,格納を行います。ただし,PALcode は割り込み可能でないため,これによって周囲のメモリが破壊されないことが保証されます。

アプリケーションを OpenVMS Alpha システムに移植する場合,ローカル・プロセッサで実行されているプロセスや,システム内の別のプロセッサで実行されているプロセス,AST ルーチンや条件ハンドラと共用しているメモリに対して,アプリケーションがバイト,ワード,またはアラインされていないロングワードの書き込みを行うかどうかを確認する必要があります。 OpenVMS Alpha システムでの細分性操作に関係する,プログラミング上の問題点についての詳細は, Migrating to an OpenVMS AXP System: Recompiling and Relinking Applications を参照してください。

  注意
INSV 命令は,細分性の維持がオンになっている場合に,細分性が正しく維持されるコードを生成しません。



細分性と不可分性の維持をどちらも有効にし,両方の維持が必要な VAX コードをコンパイラが発見すると,細分性よりも不可分性が優先されます。

たとえば,.PRESERVE=GRANULARITY を指定してコンパイルすると,命令 INCW 1(R0) は,割り込まれたら新しいワード値の書き込みをリトライします。しかし,.PRESERVE=ATOMICITY を指定してコンパイルすると,割り込まれたら初期値をフェッチしてインクリメントします。両方のオプションを指定した場合は,後者の動作になります。

また,コンパイラは,細分性を維持するアラインされていないワードおよびロングワードに対するコードを正常に生成できますが,不可分性を維持するアラインされていないワードおよびロングワードに対するコードは生成できません。両方のオプションを指定した場合には,すべてのメモリ参照はアラインされているアドレスに対するものである必要があります。

2.11.4 不可分性が保証できない場合

コンパイラの不可分性の保証は, VAX 命令のメモリ変更操作に対してだけ影響を与えるため, OpenVMS Alpha システムまたは OpenVMS I64 システムにおいて, /PRESERVE=ATOMICITY で解決できない VAX MACRO ソースのコーディング上の問題を調べる際には,特に注意する必要があります。

たとえば,次の VAX 命令があるとします。

ADDL2 (R1),4(R1) 

この命令に対して, /PRESERVE=ATOMICITY (または .PRESERVE ATOMICITY) が指定されていると,コンパイラは次のような Alpha コード・シーケンスを生成します。

        LDL     R28,(R1) 
Retry:  LDL_L   R24,4(R1) 
        ADDL    R28,R24,R24 
        STL_C   R24,4(R1) 
        BEQ     fail 
        . 
        . 
        . 
fail:   BR      Retry 

このコード・シーケンスで,STL_C が失敗すると,加算の前に変更オペランドだけが再読み込みされます。データ (R1) は再読み込みされません。この動作は VAX の動作とは少し異なります。 OpenVMS VAX システムでは,命令全体が割り込みなしで実行されます。 OpenVMS Alpha システムや OpenVMS I64 システムでは,変更オペランドだけが不可分に更新されます。

その結果,データ (R1) の読み込みが不可分であることが必要なコードでは,ロックなどの別の方法を使用して,同じレベルの同期を実現する必要があります。

この命令では,コンパイラは次の Itanium コード・シーケンスを生成します。

        ld4     r19 = [r9] 
        sxt4    r19 = r19 
        adds    r16 = 4, r9 
$L4:    ld4     r17 = [r16] 
        mov.m   apccv = r17 
        mov     r15 = r17 
        sxt4    r17 = r17 
        add     r17 = r19, r17 
        cmpxchg4.acq r17, [r16] = r17 
        cmp.eq  pr0, pr7 = r15, r17 
(pr7)   br.cond.dpnt.few $L4 

別の VAX 命令について考えます。

MOVL    (R1),4(R1) 

この命令に対して,不可分性の維持がオンの場合もオフの場合も,コンパイラは次の Alpha コード・シーケンスを生成します。

LDL     R28,(R1) 
STL     R28,4(R1) 

この例の VAX 命令は単一の VAX CPU 上で不可分ですが, Alpha 命令シーケンスは単一の Alpha CPU 上で不可分ではありません。 4(R1) オペランドが書き込みオペランドであり,変更オペランドでないため,操作は LDL_L と STL_C を使用した不可分な操作にされません。

OpenVMS I64 システムでは,コード・シーケンスは次のようになります。

ld4     r14 = [r9] 
sxt4    r14 = r14 
adds    r24 = 4, r9 
st4     [r24] = r14 

最後に,より複雑な VAX INCL 命令について考えます。

INCL    @(R1) 

この命令に対して, /PRESERVE=ATOMICITY (または .PRESERVE ATOMICITY) が指定されていると,コンパイラは次のような Alpha コード・シーケンスを生成します。

        LDL     R28,(R1) 
Retry:  LDL_L   R24,(R28) 
        ADDL    R24,#1,R24 
        STL_C   R24,(R28) 
        BEQ     fail 
        . 
        . 
        . 
fail:   BR      Retry 

ここで,変更データの更新だけが不可分です。変更データのアドレスを取得するために必要なフェッチは,不可分シーケンスの一部になっていません。

OpenVMS I64 システムでは,コード・シーケンスは次のようになります。

        ld4     r16 = [r9] 
        sxt4    r16 = r16 
$L5:    ld4     r14 = [r16] 
        mov.m   apccv = r14 
        mov     r24 = r14 
        sxt4    r14 = r14 
        adds    r14 = 1, r14 
        cmpxchg4.acq r14, [r16] = r14 
        cmp.eq  pr0, pr8 = r24, r14 
(pr8)   br.cond.dpnt.few $L5 



2.11.5 不可分性のためのアラインメントの留意事項

不可分性を維持する場合,コンパイラは変更データがアラインされているものと想定する必要があります。クォドワード境界にまたがったフィールドは, 2 つの読み取り-変更-書き込みシーケンスが必要となるため,不可分に更新できません。

OpenVMS Alpha システムでは,通常のロード命令や格納命令と異なり,アラインされていない LDx_L 命令や STx_C 命令はソフトウェアで処理できないため,アラインされていないアドレスに対する LDx_L 命令や STx_C 命令は,回復不可能な予約オペランド・フォルトを生成します。

OpenVMS I64 システムでは, compare-exchange (cmpxchg) 命令でのアラインされていないアドレスをソフトウェアで処理できないため,実行時に例外が発生します。

OpenVMS Alpha システムでは, /PRESERVE=ATOMICITY (または .PRESERVE ATOMICITY) が指定されていると, INCL (R1) 命令は LDL_L 命令および STL_C 命令を生成するため, R1 はアラインされたロングワードである必要があります。

次の命令があるとします。

INCW (R1) 

OpenVMS Alpha システムでは,この命令に対し,コンパイラは次のようなコード・シーケンスを生成します。

        BIC     R1,#^B0110,R28   ; Compute Aligned Address 
Retry:  LDQ_L   R24,(R28)        ; Load the QW with the data 
        EXTWL   R24,R1,R23       ; Extract out the Word 
        ADDL    R23,#1,R23       ; Increment the Word 
        INSWL   R23,R1,R23       ; Correctly position the Word 
        MSKWL   R24,R1,R24       ; Zero the spot for the Word 
        BIS     R23,R24,R23      ; Combine Original and New word 
        STQ_C   R23,(R28)        ; Conditionally store result 
        BEQ     fail             ; Branch ahead on failure 
        . 
        . 
        
        . 
fail:   BR      Retry 

最初の BIC 命令で, #^B0111 ではなく #^B0110 が使用されている点に注意してください。これは,ワードがクォドワード境界にまたがらないようにするためです。そうしないと,メモリの更新が不完全になります。 R1 に格納されているアドレスがアラインされているワードを指していない場合は,ビット 0 がオンになり,BIC 命令ではそのビットがクリアされません。この場合,LDQ_L (Load Quadword Locked) 命令は,回復不可能な予約オペランド・フォルトを生成します。

すべてのバイトはアラインされているため, INCB 命令では #^B0111 を使用し,アラインされたアドレスを生成します。

OpenVMS I64 システムでは, INCW (R1)命令に対して,コンパイラは次のようなコード・シーケンスを生成します。

$L5:    ld2           r19 = [r9] 
        mov.m         apccv = r19 
        mov           r18 = r19 
        sxt2          r19 = r19 
        adds          r19 = 1, r19 
        cmpxchg2.acq  r19, [r9] = r19 
        cmp.eq        pr0, pr8 = r18, r19 
(pr8)   br.cond.dpnt.few  $L5 



2.11.6 インターロックされる命令と不可分性

コンパイラが不可分性を維持する方法には,コンパイルされた VAX MACRO コードにおいて興味深い副作用があります。

OpenVMS VAX システムでは,マルチプロセッサ・システムにおける共用データへのアクセスを同期させる方法としては,インターロックされる命令だけが正常に機能します。 OpenVMS Alpha のマルチプロセシング・システムでは,不可分性が維持される変更命令とインターロックされる命令をコンパイルした結果得られるコードは,どちらも正常に機能します。これは,コンパイラが両方の命令セットに対して生成する LDx_L と STx_C が,複数のプロセッサにわたって正しく動作するためです。同様に, OpenVMS I64 システムでは, compare-exchange (cmpxchg) 命令が,プロセッサにまたがったインターロック機能を提供します。

このコンパイラの副作用は OpenVMS Alpha システムと OpenVMS I64 システムに固有であり, OpenVMS VAX システムには該当しないため, VAX MACRO コードを OpenVMS Alpha または OpenVMS I64 に移植する際に,コードを両方のシステムで動作させる予定の場合は,この副作用に頼らないようにしてください。

しかし,不可分性が維持されない他の命令に対するインターロックとしてメモリ変更が使用されている場合は,インターロックされる命令を使用する必要があります。これは,Alpha アーキテクチャと Itanium アーキテクチャでは,書き込み順序が厳密には保証されないためです。

たとえば,次の VAX MACRO コード・シーケンスがあるとします。

.PRESERVE ATOMICITY 
INCL (R1) 
.NOPRESERVE ATOMICITY 
MOVL (R2),R3 

このコード・シーケンスから,次の Alpha コード・シーケンスが生成されます。

Retry:  LDL_L   R28,(R1) 
        ADDL    R28,#1,R28 
        STL_C   R28,(R1) 
 
        BEQ     R28, fail 
        LDL     R3, (R2) 
         . 
         . 
         . 
fail:   BR      Retry 

Alpha アーキテクチャと Itanium アーキテクチャのデータ・フェッチ動作に起因して,(R1) への格納が処理されるよりも前に (R2) からデータが読み込まれる可能性があります。 INCL (R1) 命令をロックとして使用し,ロックが設定される前に (R2) のデータがアクセスされないようにすると, (R1) のインクリメントよりも前に (R2) の読み込みが行われる可能性があり,保護されません。

VAX のインターロックされる命令では,インターロックされる命令の前後に Alpha の MB (メモリ・バリア) 命令または Itanium の mf (メモリ・フェンス) 命令が生成されます。これにより,インターロックされる命令をまたいでメモリのロードが移動されなくなります。

OpenVMS I64 では,コード・シーケンスは次のようになります。

$L7:    ld4     r16 = [r9] 
        mov.m   apccv = r16 
        mov     r15 = r16 
        sxt4    r16 = r16 
        adds    r16 = 1, r16 
        cmpxchg4.acq r16, [r9] = r16 
        cmp.eq  pr0, pr10 = r15, r16 
(pr10)  br.cond.dpnt.few $L7 
        ld4     r3 = [r28] 
        sxt4    r3 = r3 

次のコード・シーケンスがあるとします。

ADAWI     #1,(R1) 
MOVL      (R2),R3 

このコード・シーケンスは,次の Alpha コード・シーケンスを生成します。

        MB 
Retry:  LDL_L   R28,(R1) 
        ADDL    R28,#1,R28 
        STL_C   R28,(R1) 
 
        BEQ     R28, Fail 
        MB 
        LDL     R3, (R2) 
         . 
         . 
         . 
Fail:   BR      Retry 
 

OpenVMS I64 では,次のようなコード・シーケンスが生成されます。

        mf 
$L8:    ld2     r23 = [r9] 
        mov.m   apccv = r23 
        adds    r24 = 1, r23 
        cmpxchg2.acq r14, [r9] = r24 
        cmp.eq  pr0, pr11 = r23, r14 
(pr11)  br.cond.dpnt.few $L8        
        mf 
        ld4     r3 = [r28] 
        sxt4    r3 = r3 

MB 命令または mf 命令があると,その前にあるすべてのメモリ操作が完了してからその後のメモリ操作が開始されるようになります。

注意

1 このマニュアルはアーカイブ扱いになっています。このマニュアルの保守は行われておらず, OpenVMS ドキュメント・セットにも含まれていません。ただし,http://www.hp.com/go/openvms/doc からオンラインで参照することができます。


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.