【PL/I深掘り】ALIGNとUNALIGNEDの「境界」がバッチ性能とメモリを支配する
若手の諸君、日々のバッチ改修お疲れ様。
夜間バッチのウィンドウが迫る中、「なぜか計算処理が遅い」「データ構造を変更したらレコード長が合わなくなった」といったトラブルに頭を抱えたことはないか?
今回は、PL/Iのデータ構造において、パフォーマンスとメモリ効率の「生死」を分けるALIGN(境界調整)とUNALIGNED(非境界調整)について紐解いていく。メインフレームの世界では、コンパイラ任せのデフォルト設定を理解せずにコーディングするのは、目隠しで高速道路を走るようなものだ。
—
なぜ「境界(Boundary)」を意識しなければならないのか
PL/Iにおいて、`ALIGN`は変数を境界(通常は4バイトや8バイトの倍数)に配置しようとする属性だ。CPUは「メモリのキリが良い場所」にあるデータを読み込むのが最も速い。一方で`UNALIGNED`は、文字通り「パディング(詰め物)」を排除し、メモリを極限まで節約する。
- ALIGN (デフォルト): CPUアクセス最適化。メモリ上に隙間(パディング)が生まれるため、構造体サイズは大きくなる。
- UNALIGNED: メモリ節約。パディングを許さないため、レコード入出力のサイズ抑制には強力だが、アクセス速度はわずかに犠牲になる。
特にVSAMやQSAMで外部ファイルとデータをやり取りする際、この属性の不一致は「致命的なデータ不整合」を招く。COBOLのCOPY句からPL/Iの構造体に変換する際、デフォルトの挙動の違いで夜通しデバッグした経験はないだろうか?
—
実践:構造体定義とメモリ配置の制御
以下のコードを見てほしい。実務で頻出する、構造体定義のベストプラクティスだ。
/i
/ PACKAGEは構造の明確化と名前空間の管理に必須 /
TEST_PROG: PACKAGE;
/ メイン処理PROCEDURE /
BATCH_MAIN: PROCEDURE OPTIONS(MAIN);
/
- 【重要】ALIGNとUNALIGNEDの使い分け例
- 内部計算用ワークはALIGNで速度優先、
- ファイルI/O用構造体はUNALIGNEDでレイアウト固定が鉄則。
/
/ 外部ファイルレイアウト用(パディング禁止) /
DCL 1 RECORD_IO_AREA UNALIGNED,
5 KEY_ID CHAR(8),
5 DATA_VAL FIXED BIN(31),
5 STATUS_CODE CHAR(1);
/ 内部計算用ワーク(速度優先) /
DCL 1 WORK_AREA ALIGNED,
5 WORK_VAL_A FIXED BIN(31),
5 WORK_VAL_B FIXED BIN(31);
/ BUILTIN関数による安全な操作 /
DCL (ADDR, LENGTH) BUILTIN;
/ ONユニットでの例外制御 /
ON ENDFILE(SYSIN) BEGIN;
PUT SKIP LIST(‘データ終了を確認しました。’);
END;
/ 処理ロジック /
RECORD_IO_AREA.DATA_VAL = 100;
WORK_AREA.WORK_VAL_A = RECORD_IO_AREA.DATA_VAL 2;
PUT SKIP LIST(‘処理結果:’, WORK_AREA.WORK_VAL_A);
END BATCH_MAIN;
END TEST_PROG;
—
トラブルシューティングの勘所
現場で「なぜかデータが化ける」「VSAMの読み込みでオフセットがずれる」という事態に直面したとき、真っ先に確認すべきは以下の3点だ。
1. コンパイラオプションの確認: `ALIGN`がデフォルトのコンパイラと、プロジェクト全体で`UNALIGNED`を強制している環境では挙動が異なる。まずはコンパイルリストのプロローグを眺める癖をつけよう。
2. `DEFINED` 属性との組み合わせ: `DEFINED`を使って構造体の一部を再定義する際、`ALIGN`の境界調整によって意図せぬ位置にデータが配置されることがある。`SUBSTR`や`BIT`操作を多用する箇所では特に注意が必要だ。
3. パフォーマンスの罠: `UNALIGNED`はメモリは節約できるが、CPUが「ズレたデータ」をロードする際に複数回のメモリアクセスを発生させることがある。超大規模なループ処理の中でこの構造体を使う場合、計算ワークだけは`ALIGN`属性の変数へ転送してから処理する工夫が、バッチ時間を数分単位で短縮することに繋がる。
最後に:エンジニアとしての矜持
メインフレームにおけるPL/Iは、今や「枯れた技術」ではない。「安定して高速にビジネスを支え続ける熟成された技術」だ。
境界調整のような低レイヤーの知識は、一見すると現代のクラウド開発では不要に見えるかもしれない。しかし、「なぜそのメモリ配置なのか」を論理的に説明できるエンジニアこそが、大規模マイグレーションや、不可解なシステム障害を解決できる唯一の存在だ。
明日からのコード修正では、ただ動くだけでなく、そのデータ構造の「境界」が最適化されているか、一度立ち止まって考えてみてほしい。それこそが、プロのシステムアーキテクトへの第一歩だ。
健闘を祈る。何かあればまたいつでも聞いてくれ。
