[ 前のページ ]
[ 次のページ ]
[ 目次 ]
[ 索引 ]
[ DOC Home ]
Alpha Architecture Reference Manual, Third Edition (AARM) に,インターロックされたメモリ命令を使用するための厳密な規則が説明されています。 新しいAlpha 21264 (EV6)プロセッサと将来のすべてのAlpha プロセッサは,これらの規則で決められている必要条件に関して, 以前のプロセッサよりさらに厳しくなっています。この結果,規則に準拠していないにもかかわらず, 以前は正常に動作していたコードが,新しい21264 プロセッサを搭載したシステムで正しく実行できないことがあります。 このような規則に準拠していないコード・シーケンスが発生することは非常にまれであると考えています。 21264プロセッサは, OpenVMS Alphaバージョン7.1-2より以前のバージョンではサポートされません。
規則に従っていないコードを実行すると,インタープロセッサ・ロックが使用されるときに, プロセッサ間の同期が失われる可能性があり,インターロックされたシーケンスが常にエラーになる場合は, 無限ループになることがあります。BLISS コンパイラの以前のバージョン,MACRO-32コンパイラとMACRO-64 アセンブラの一部のバージョンでコンパイルされたプログラムや, 一部のDEC CおよびC++プログラムのコード・シーケンスで,このような動作が発生することがあります。
影響を受けるコード・シーケンスでは,LDx_L/STx_C命令をアセンブリ言語ソースで直接使用しているか, コンパイラで生成されたコードで使用しています。 インターロックされた命令を使用する可能性の高いアプリケーションは複雑であるか, マルチスレッドされたアプリケーションであるか, または高度に最適化され,手作りのロックおよび同期化手法を使用しているデバイス・ ドライバです。
OpenVMSでは,21264プロセッサで実行されるコードにこのようなシーケンスがないかどうか確認するように推奨しています。 プロセス間ロック,マルチスレッド, プロセッサ間通信を行うコードでは,特に注意を払う必要があります。
規則に準拠していないコード・シーケンスがないかどうか,Alpha実行可能プログラムを分析するために,SRM_CHECK ツールが開発されました(Alpha アーキテクチャを定義したSystem Reference Manualの後に開発されました) 。このツールは,エラーが発生する可能性のあるシーケンスを検出し, エラーを報告し,問題のあるシーケンスのマシン・コードを表示します。
SRM_CHECKツールは,OpenVMS Alphaバージョン7.2オペレーティング・システムのCD-ROM の次の場所にあります。
SYS$SYSTEM:SRM_CHECK.EXE
SRM_CHECKツールを実行するには,フォーリン・コマンドとして定義し( またはDCL$PATH機能を使用し),チェックするイメージの名前を指定して起動します。 問題が検出されると,マシン・コードが表示され,イメージ情報の一部が印刷されます。 次の例では,このツールを使用してmyimage.exe というイメージを分析する方法を示しています。
$ define DCL$PATH [] $ srm_check myimage.exe
このツールでは,ワイルドカード検索がサポートされます。ワイルドカード検索を開始するには, 次のコマンド行を使用します。
$ srm_check [*...]* -log
チェックされたイメージのリストを作成するには,-log修飾子を指定します。-output 修飾子を使用すれば,出力をデータ・ファイルに書き込むことができます。 たとえば,次のコマンドは出力をCHECK.DATという名前のファイルに書き込みます。
$ srm_check 'file' -output check.dat
ツールからの出力を使用し,イメージのMAPファイルを調べれば,シーケンスを生成したモジュールを検索することができます。 表示されるアドレスはMAP ファイルから見つけることができるアドレスに直接対応します。
次の例では,SYSTEM_SYNCHRONIZATION.EXEというイメージに対して,分析ツールを使用した結果作成される出力を示しています。
** Potential Alpha Architecture Violation(s) found in file... ** Found an unexpected ldq at 00003618 0000360C AD970130 ldq_l R12, 0x130(R23) 00003610 4596000A and R12, R22, R10 00003614 F5400006 bne R10, 00003630 00003618 A54B0000 ldq R10, (R11) Image Name: SYSTEM_SYNCHRONIZATION Image Ident: X-3 Link Time: 5-NOV-1998 22:55:58.10 Build Ident: X6P7-SSB-0000 Header Size: 584 Image Section: 0, vbn: 3, va: 0x0, flags: RESIDENT EXE (0x880)
system_synchronization.exeのMAPファイルには,次の情報が格納されます。
EXEC$NONPAGED_CODE 00000000 0000B317 0000B318 ( 45848.) 2 ** 5 SMPROUT 00000000 000047BB 000047BC ( 18364.) 2 ** 5 SMPINITIAL 000047C0 000061E7 00001A28 ( 6696.) 2 ** 5
アドレス360CはSMPROUTモジュールにあり,0〜47BBのアドレスを格納しています。 モジュールから出力されたマシン・コードを確認することで,コードの位置を調べ, リスト行番号を使用して,対応するソース・コードを突き止めることができます。SMPROUT のベースが0以外の場合は,アドレス( この場合は360C)からベースを減算して,リスト・ファイル内での相対アドレスを求める必要があります。
このツールは,出力に可能性のある違反を報告します。SRM_CHECK は通常,セクションの属性によってイメージ内のコード・セクションを識別することができますが,OpenVMS イメージの場合は,同じ属性を持つデータ・ セクションが格納されることがあります。この結果,SRM_CHECKはデータをコードであるかのようにスキャンし, データ・ブロックが規則に準拠していないコード・ シーケンスであると解釈することがあります。このような状況はあまり発生することがなく,MAP とリスト・ファイルを調べることで検出できます。
SRM_CHECKツールによって検出される規則に準拠しないコードは,次の4種類に分類できます。 これらの大部分は,新しいコンパイラで再コンパイルすることで修正できます。 ソース・コードを変更しなければならないことがありますが, そのような場合はまれです。コンパイラのバージョンの詳細については, 第7.5節を参照してください。
この問題は再コンパイルすることで対処できます。
この問題は再コンパイルすることで対処できます。
この問題は再コンパイルすることで対処できます。
この問題が発生する場合は,ソース・コードを変更しなければなりません。 新しいMACRO-32コンパイラは,コンパイル時に規則に準拠しないコードにフラグを付けます。
SRM_CHECKツールがイメージから違反を検出した場合は,適切なコンパイラを使用してイメージを再コンパイルしなければなりません( 第7.5節を参照)。再コンパイルした後, イメージを再び分析する必要があります。 再コンパイルの後も違反が発生する場合は, ソース・コードを調べ,コード・スケジューリング違反が発生する理由を突き止めなければなりません。 その後,必要に応じてソース・コードを変更します。
Alpha Architecture Reference Manualには,プロセッサ間のデータの不可分な更新を行う方法が説明されています。 特に,Third Edition にはこの問題について非常に詳しい説明があります。このエディションの5.5 節「Data Sharing」と,LDx_L命令について説明した4.2.4項には,インターロックされたメモリ・ シーケンスの規則について詳しく説明されています。
次の2つの必要条件が満たされない場合は,規則に準拠しないコードが生成されます。
ターゲットがLDx_Lとそれに対応するSTx_Cの間にある分岐を実行すると, 規則に準拠しないシーケンスが作成されます。たとえば,次の例で"label" への分岐を実行すると,分岐命令自体がシーケンスの内部にあるのか外部にあるのかとは無関係に, 規則に準拠しないコードが作成されます。
LDx_L Rx, n(Ry) ... label: ... STx_C Rx, n(Ry)
したがって,SRM_CHECKツールは次の条件を検索します。
これは通常,LDx_LからSTx_Cへ逆方向分岐が実行されることを示します。 ただし,デバイス・メールボックス書き込みを実行するハードウェア・ デバイス・ドライバは例外です。これらのドライバでは,メールボックスに書き込むためにSTx_C を使用します。この状況は初期のAlpha システムでのみ検出され,PCIベースのシステムでは検出されません。
AARMは,LDx_lとSTx_cの間の命令の数を40未満になるように推奨しています。 理論的には,40より多くの命令があると,シーケンスが完了しないようにするためにハードウェア割り込みが発生します。 しかし, この状況が発生したという報告はありません。
次の例は,SRM_CHECKでフラグが付けられたコードを示しています。
** Found an unexpected ldq at 0008291C 00082914 AC300000 ldq_l R1, (R16) 00082918 2284FFEC lda R20, 0xFFEC(R4) 0008291C A6A20038 ldq R21, 0x38(R2)
この例で,対応するSTQ_Cより前に,LDQ_Lの後からLDQ命令が検出されています。LDQ は再コンパイルするか,ソース・コードを変更することで, シーケンスの外部に移動しなければなりません(第7.3 節を参照)。
** Backward branch from 000405B0 to a STx_C sequence at 0004059C 00040598 C3E00003 br R31, 000405A8 0004059C 47F20400 bis R31, R18, R0 000405A0 B8100000 stl_c R0, (R16) 000405A4 F4000003 bne R0, 000405B4 000405A8 A8300000 ldl_l R1, (R16) 000405AC 40310DA0 cmple R1, R17, R0 000405B0 F41FFFFA bne R0, 0004059C
この例では,LDL_LとSTQ_Cの間から分岐が検出されています。この場合, LDx_LとSTx_Cの間に,アーキテクチャで要求されている"フォール・スルー" パスがありません。
次のMACRO-32ソース・コードは"フォール・スルー"パスがあるものの,ロック・ シーケンス内に可能性のある分岐とメモリ参照があるために,規則に準拠しないコードを示しています。
getlck: evax_ldql r0, lockdata(r8) ; Get the lock data movl index, r2 ; and the current index. tstl r0 ; If the lock is zero, beql is_clear ; skip ahead to store. movl r3, r2 ; Else, set special index. is_clear: incl r0 ; Increment lock count evax_stqc r0, lockdata(r8) ; and store it. tstl r0 ; Did store succeed? beql getlck ; Retry if not.
このコードを修正するには,INDEXの値を読み込むためのメモリ・アクセスを最初にLDQ_L/STQ_C シーケンスの外部に移動しなければなりません。 次に,ラベルIS_CLEARへの,LDQ_LとSTQ_Cの間の分岐を取り除かなければなりません。 この場合,CMOVEQ命令を使用して分岐を取り除くことができます。 単純な値の移動の周囲にある分岐を取り除くには,多くの場合, CMOVxx命令が役立ちます。次の例では修正されたコードを示しています。
movl index, r2 ; Get the current index getlck: evax_ldql r0, lockdata(r8) ; and then the lock data. evax_cmoveq r0, r3, r2 ; If zero, use special index. incl r0 ; Increment lock count evax_stqc r0, lockdata(r8) ; and store it. tstl r0 ; Did write succeed? beql getlck ; Retry if not.
ここでは,規則に準拠しないコード・シーケンスを生成する可能性のあるコンパイラのバージョンと, 再コンパイルするときに使用する推奨バージョンについて説明します。
表 7-1にOpenVMSコンパイラの情報を示します。
以前のバージョン | 推奨されるバージョン |
---|---|
BLISS V1.1 | BLISS V1.3 以上 |
DEC C V5.x | DEC C V6.0以上 |
DEC C++ V5.x | DEC C++ V6.0以上 |
DEC Pascal V5.0- 2 | DEC Pascal V5.1-11以上 |
MACRO-32 V3.0 | V3.1 for OpenVMS Version 7.1-2以上 V4.1 for OpenVMS Version 7.2以上 |
MACRO-64 V1.2 | 下記参照 |
MACRO-64アセンブラの現在のバージョンでも,ループ回転の問題がまだ発生することがあります。 しかし,MACRO-64ではデフォルトでコードの最適化が実行されないので, この問題が発生するのは,最適化が有効に設定されている場合だけです。SRM_CHECK がMACRO-64コードから規則に準拠しないシーケンスを検出した場合は, 最初に最適化せずに再コンパイルする必要があります。 その後,再びテストしてもシーケンスにフラグが付けられる場合は, ソース・コード自体に修正の必要な非準拠シーケンスが含まれています。
MACRO-32 Compiler for OpenVMS Alphaバージョン4.1では,非準拠コード・ シーケンスを検出するための追加コード・チェックが実行され,警告メッセージが表示されるようになりました。 次の警告メッセージが表示されることがあります。
説明: コンパイラはLDx_L/STx_Cシーケンスの内部から.BRANCH_LIKELY ディレクティブを検出しました。
対処法: 対処は必要ありません。コンパイラは.BRANCH_LIKELYディレクティブを無視します。 他にコーディング・ガイドラインの違反がない限り, コードは指定されたとおりに動作します。
説明: 分岐命令のターゲットがLDx_L/STx_Cシーケンスの内部にあります。
対処法: この警告を回避するには, ソース・コードを変更して,LDx_L/STx_Cシーケンスの内部の分岐またはこのシーケンスへの分岐をなくさなければなりません。 インターロックされたシーケンスからの分岐は有効であり, フラグは付けられません。
説明: LDx_L/STx_Cシーケンスの内部でメモリ読み込みまたは書き込みが発生します。 これは,"MOVL data, R0"などのように,ソース・ コード内の明示的な参照であるか,またはメモリへの暗黙の参照です。 たとえば,データ・ラベルのアドレスのフェッチ(たとえば"MOVAB label, R0")は,リンク・セクション,外部参照を解決するために使用されるデータ領域からの読み込みによって行われます。
対処法: この警告を回避するには, すべてのメモリ・アクセスをLDx_L/STx_Cシーケンスの外部に移動します。
説明: コンパイラがLDx_L命令の後,STx_C命令の前にRET またはRSB命令を検出しました。これは不正な形式のロック・シーケンスを示します。
対処法: LDx_L命令とSTx_C命令の間にRET 命令やRSB命令が指定されないように,コードを変更します。
説明: ルーチン呼び出しがLDx_L/STx_Cシーケンスの内部で発生します。 これは"JSBサブルーチン"などのソース・コード内の明示的なCALL/JSB であるか,または他の命令の結果発生する暗黙の呼び出しです。 たとえば,MOVCやEDIVなどの一部の命令は,実行時ライブラリへの呼び出しを生成します。
対処法: この警告を回避するには,コンパイラで示されたルーチン呼び出しまたはその呼び出しを生成する命令をLDx_L/STx_C シーケンスの外部に移動します。
説明: コンパイラがLDx_L命令より前にSTx_C命令を検出しました。 これは不正な形式のロック・シーケンスを示します。
対処法: STx_C命令がLDx_L命令の後にくるように, コードを変更します。
OpenVMS AlphaのMACRO-32コードのうち,SYS$LIBRARY:LIB.MLBマクロ・ライブラリからALONONPAGED_INLINE またはLAL_REMOVE_FIRSTマクロを起動するコードは,OpenVMS バージョン7.2で再コンパイルして,これらのマクロの正しいバージョンが取得されるようにしなければなりません。 これらのマクロを変更すると, 新しいAlpha 21264 (EV6)プロセッサで検出される可能性のある同期化に関する問題を修正できます。
[ 前のページ ]
[ 次のページ ]
[ 目次 ]
[ 索引 ]
[ DOC Home ]