なぜ今、PL/Iの「MAP」を読み解く必要があるのか
メインフレームの現場で、長年凍結されていた巨大なバッチプログラムの改修を任されたとき、一番の恐怖は「どこをいじるとメモリが壊れるか分からない」という不安ではないでしょうか。
PL/Iは、その柔軟すぎるデータ構造ゆえに、型指定が曖昧なままだと意図しないアライメント調整が入り、予期せぬパフォーマンス劣化や、最悪の場合はABENDを引き起こします。特に、VSAMファイルや固定長レコードとのI/Oが絡む処理では、構造体のオフセット一つが命取りです。
今回は、コンパイラオプション `MAP` を駆使し、コンパイルリスト(SYSPRINTに出力される魔法の地図)からメモリレイアウトを紐解き、最適化する技術について解説します。
—
コンパイルリストの「MAP」セクションを読み解く
コンパイルオプションに `MAP` を指定すると、リスト出力の末尾付近に「Storage Map」が出力されます。ここには、コンパイラが各変数をメモリ上のどこに配置したかが克明に記されています。
注目すべきは以下の3点です:
1. OFFSET: データブロックの先頭からの相対位置。
2. LENGTH: 変数が実際に占有しているバイト数。
3. ALIGNMENT: その変数がメモリの境界(Boundary)に正しく配置されているか。
もし、構造体の中で不自然な「隙間(Padding)」が空いている場合、それはCPUのアクセス効率を落とす原因となります。特に `ALIGNED` 属性と `UNALIGNED` 属性の混在は要注意です。
—
実践:構造体の配置最適化コード例
以下のコードは、VSAMレコードを読み込み、内部で集計を行う際によく見られる構造体定義です。ここでの配置を最適化してみましょう。
/i
/——————————————————————-/
/ 構造体のメモリレイアウトを意識したコーディング例 /
/——————————————————————-/
TEST_PROC: PROCEDURE OPTIONS(MAIN);
/ 構造体定義:ALIGNEDを指定して境界合わせを明示的に制御する /
/ これにより、MAP出力でのOFFSETが予測可能なものとなる /
DCL 1 VSAM_RECORD ALIGNED,
3 KEY_ID CHAR(8), / キー項目: 8バイト /
3 TRANS_TYPE FIXED BIN(15),/ 処理種別: 2バイト /
3 FILLER CHAR(2), / パディング: 境界調整用 /
3 AMOUNT FIXED DEC(15,2); / 金額: 8バイト(PACKED) /
/ BUILTIN関数による安全な操作とONユニットの基本 /
ON ENDFILE(SYSIN) BEGIN;
PUT SKIP LIST(‘入力終了。処理を正常に終了します。’);
STOP;
END;
/ 処理本体:ここでメモリ配置が適切であれば、 /
/ CPUキャッシュのヒット率が向上し、バッチ時間が短縮される /
DO WHILE(1);
READ FILE(SYSIN) INTO(VSAM_RECORD);
/ 固定長レコード操作時の典型的なバリデーション /
IF LENGTH(TRIM(VSAM_RECORD.KEY_ID)) > 0 THEN DO;
/ 内部演算処理… /
END;
END;
END TEST_PROC;
なぜ `FILLER` を入れるのか?
上記のコードで `FIXED BIN(15)` の後にわざわざ `FILLER` を入れたのは、次の `FIXED DEC` が4バイト境界(あるいは8バイト境界)で始まることを保証するためです。これを怠ると、コンパイラが自動的にパディングを挿入し、`MAP` 上で想定外のオフセットが発生します。特に外部システムとバイナリデータをやり取りする場合、このオフセットのズレは致命的なデータ破損を招きます。
—
トラブルシューティングの極意
現場で「なぜかデータがずれる」「特定の環境だけで桁落ちする」という相談を受けた際、私がまず確認するのはこの `MAP` オプションの結果です。
1. 属性の確認: `UNALIGNED` で定義された構造体を、`ALIGNED` が前提のサブルーチンに渡していないか?
2. ストレージの重複: `DEFINED` 句を多用しすぎて、メモリレイアウトがスパゲッティ化していないか?
3. コンパイラ最適化との兼ね合い: `OPT(2)` 以上の最適化をかけると、`MAP` 上の変数がレジスタに保持され、メモリ上の値と一致しなくなることがあります。デバッグ時は `MAP` と `LIST` (生成コードの確認) を併用するのが鉄則です。
結び
メインフレームのコードは、単に動けば良いというものではありません。メモリの「呼吸」を感じられるような、無駄のない美しい配置こそが、保守性の高い、そして何十年も稼働し続けるシステムを支えるのです。
次回の改修作業では、ぜひコンパイルリストの最後にある `MAP` セクションを開いてみてください。そこには、あなたの書いたソースコードが、機械(ハードウェア)とどう対話しているかの「真実」が記されています。
何かあれば、いつでも相談してください。このレガシーな世界の深淵を、共に渡り歩いていきましょう。
