前へ | 次へ | 目次 | 索引 |
インターロックされたメモリ命令を使用するための厳密な規則は,『Alpha Architecture Reference Manual, Third Edition (AARM)』に説明されています。Alpha 21264 (EV6) プロセッサと将来のすべてのAlpha プロセッサは, これらの規則で決められている必要条件に関して,以前のプロセッサよりさらに厳しくなっています。この結果,以前は規則に準拠していなくても正常に動作していたコードが,21264 以降のプロセッサを搭載したシステムでは正しく実行できないことがあります。このような規則に準拠していないコード・シーケンスが発生することは,非常にまれであると考えられています。 21264 プロセッサは,OpenVMS Alpha バージョン 7.1-2 より前のバージョンではサポートされません。
規則に従っていないコードを実行すると,インタープロセッサ・ロックが使用されるときに,プロセッサ間の同期が失われる可能性があり,インターロックされたシーケンスが常にエラーになる場合は,無限ループになることがあります。BLISS コンパイラの以前のバージョン,MACRO--32 コンパイラと MACRO--64 アセンブラの一部のバージョンでコンパイルされたプログラムや,一部の Compaq C および C++ プログラムのコード・シーケンスで, このような動作が発生することがあります。
影響を受けるコード・シーケンスでは,LDx_L/STx_C 命令を,アセンブリ言語ソースで直接,またはコンパイラで生成されたコードで使用しています。インターロックされた命令を使用する可能性の高いアプリケーションは複雑であるか,マルチスレッドされたアプリケーションであるか,または高度に最適化された固有に作成したロックおよび同期化手法を使用しているデバイス・ドライバです。
8.1 必要なコード・チェック
OpenVMS では,21264 プロセッサで実行されるコードにこのようなシーケンスがないかどうか確認してください。プロセス間ロック,マルチスレッド,プロセッサ間通信を行うコードでは,特に注意する必要があります。
Alpha 実行可能プログラムを分析して,規則に準拠していないコード・シーケンスがあるかどうか調べるために,SRM_CHECK ツール ( Alpha アーキテクチャを定義した『Code Management System Reference Manual』にちなんで命名 ) が開発されました。このツールは,エラーが発生する可能性のあるシーケンスを検出し,エラーを報告し,問題のあるシーケンスのマシン・コードを表示します。
8.2 コード分析ツールの使用
SRM_CHECK ツールは,OpenVMS Alpha Version 7.3 Operating System 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 とリスト・ファイルを調べることで検出できます。
8.3 規則に準拠しないコードの特徴
SRM_CHECK ツールによって検出される規則に準拠しないコードは,次の 4 つに分類できます。これらの大部分は,新しいコンパイラで再コンパイルすることで修正できます。ソース・コードを変更しなければならないことがありますが,そのような場合はまれです。コンパイラのバージョンの詳細については, 第 8.5 節 を参照してください。
この問題は再コンパイルすることで対処できます。
この問題は再コンパイルすることで対処できます。
この問題は再コンパイルすることで対処できます。
この問題が発生する場合は,ソース・コードを変更しなければなりません。新しい MACRO--32 コンパイラは,規則に準拠しないコードに対して,コンパイル時にフラグを付けます。
SRM_CHECK ツールがイメージから違反を検出した場合は,適切なコンパイラを使用してイメージを再コンパイルしなければなりません ( 第 8.5 節 を参照)。再コンパイルした後,イメージを再び分析する必要があります。再コンパイルの後も違反が発生する場合は,ソース・コードを調べ,コード・スケジューリング違反が発生する原因を追求しなければなりません。その後,必要に応じてソース・コードを変更します。
8.4 コーディングの必要条件
『Alpha Architecture Reference Manual』では,プロセッサ間のデータの不可分な更新を実行する方法を説明しています。特に『Third Edition』には,この問題に関するさらに詳しい情報が含まれています。また,インターロックされたメモリ・シーケンスの規則について詳しく説明されています。
次の 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) |
この例では,LDQ 命令が LDQ_L の後,STQ_C の前に検出されています。 LDQ は,再コンパイルまたはソース・コードの変更によって,このシーケンスの外部に移動しなければなりません ( 第 8.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 の間に,アーキテクチャで要求されている「フォール・スルー」パスがありません。
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. |
ここでは,規則に準拠しないコード・シーケンスを生成する可能性のあるコンパイラのバージョンと,再コンパイルするときに使用する推奨バージョンについて説明します。
表 8-1 に,OpenVMS コンパイラの情報を示します。
旧いバージョン | 推奨最小バージョン |
---|---|
BLISS V1.1 | BLISS V1.3 |
DEC Ada V3.5 | Compaq Ada V3.5A |
DEC C V5.x | DEC C V6.0 |
DEC C++ V5.x | DEC C++ V6.0 |
DEC COBOL V2.4,V2.5 | Compaq COBOL V2.6 |
DEC Pascal V5.0-2 | DEC Pascal V5.1-11 |
MACRO--32 V3.0 | OpenVMS バージョン 7.1-2 については V3.1
OpenVMS バージョン 7.2 については V4.1 |
MACRO--64 V1.2 | 下記参照 |
MACRO--64 アセンブラの現在のバージョンでも,ループ回転の問題が発生することがあります。しかし,MACRO--64 ではデフォルトでコードの最適化が実行されないので,この問題が発生するのは,最適化が有効に設定されている場合だけです。 SRM_CHECK が MACRO--64 コードから規則に準拠しないシーケンスを検出した場合は,最初に最適化せずに再コンパイルする必要があります。その後,再びテストしてもシーケンスにフラグが付けられる場合は,ソース・コード自体に修正の必要な非準拠シーケンスが含まれています。
8.6 ALONONPAGED_INLINE マクロまたは LAL_REMOVE_FIRST マクロによるコードの再コンパイル
OpenVMS Alpha の MACRO--32 コードのうち,SYS$LIBRARY:LIB.MLB マクロ・ライブラリから ALONONPAGED_INLINE マクロまたは LAL_REMOVE_FIRST マクロを起動するコードは,OpenVMS バージョン 7.2 以降で再コンパイルして,これらのマクロの正しいバージョンが取得されるようにしなければなりません。これらのマクロを変更すると,新しい Alpha 21264 (EV6) 以降のプロセッサで検出される可能性のある,同期化に関する問題を修正できます。
EXE$ALONONPAGED ルーチン (またはその変形) を呼び出すソース・モジュールは,再コンパイルする必要がありません。これらのモジュールは,ユーザに意識させることなく,このリリースに含まれているルーチンの正しいバージョンを使用します。 |
前へ | 次へ | 目次 | 索引 |