【PL/I深掘り】ALIGNED vs UNALIGNED:メインフレームのメモリ効率を支配する「境界調整」の美学
メインフレームの現場で何十年も戦っていると、時折「なぜか計算処理が遅い」「構造体のサイズが想定より大きくて、ファイルI/Oでバッファ溢れを起こした」といった相談を受ける。その原因の多くは、PL/Iにおける`ALIGNED`と`UNALIGNED`の理解不足、つまり「境界調整(Alignment)」の制御にある。
今日は、若手エンジニアがつい見落としがちなこの「メモリとCPUのトレードオフ」について、実務の視点から紐解いていこう。
—
1. なぜ「境界調整」が必要なのか?
PL/Iのコンパイラは、デフォルトではデータ型に応じて「最もアクセス効率の良いメモリ境界」に配置しようとする。これを`ALIGNED`と呼ぶ。例えば、4バイトの固定小数点数(FIXED BINARY(31))であれば、4の倍数のアドレスから開始させるのが最も速い。CPUがメモリからデータを一度の命令で読み込めるからだ。
しかし、その代償として「パディング(詰め物)」が発生する。
一方、`UNALIGNED`は「詰め物を許さず、文字通り隙間なく詰め込む」設定だ。メモリ容量は節約できるが、CPUが「境界をまたいだデータ」を読み取るために内部で追加の処理を行う必要があり、実行速度が犠牲になる可能性がある。
2. 構造体配列における「静かなる膨張」
特に注意が必要なのが、大規模な構造体配列だ。以下のコードを見てほしい。
/i
/ 構造体の定義例 /
DCL 1 EMPLOYEE_REC,
2 ID FIXED BIN(31) ALIGNED, / 4バイト境界に配置 /
2 NAME CHAR(10), / 非境界調整 /
2 SALARY FIXED BIN(31) ALIGNED;
/ 配列として定義した場合の罠 /
DCL EMP_TABLE(1000) LIKE EMPLOYEE_REC;
`ALIGNED`属性を明示、あるいはデフォルトで適用している場合、`NAME`の後ろにパディングが自動挿入され、`SALARY`が再び4バイト境界に揃えられる。1レコードあたり数バイトのロスだが、これが100万件のバッチ処理になれば、メモリ上の占有量は無視できない差となり、VSAMのブロックサイズ設計にも悪影響を及ぼす。
3. 実践:性能と効率のバランスをとる
VSAMやQSAMでレコードを読み書きする場合、`UNALIGNED`で定義しておかないと、ファイルレイアウトとメモリ上の配置が一致せず、予期せぬオフセットずれが生じることがある。
以下に、実務で使える「効率を意識した定義」のサンプルを示す。
/i
/ PACKAGEは構造の基本。モジュール単位のスコープを明確にする /
BATCH_PROCESS: PACKAGE OPTIONS(MAIN);
/ 構造体定義:入出力用はUNALIGNEDを推奨 /
DCL 1 VSAM_RECORD UNALIGNED,
2 RECORD_TYPE CHAR(1) INIT(‘A’),
2 SEQ_NUM FIXED BIN(15),
2 DATA_VAL FIXED BIN(31);
/ プロシージャ内で効率的に処理する例 /
PROCESS_DATA: PROC;
DCL I FIXED BIN(31);
ON ENDFILE(SYSIN) BEGIN;
PUT SKIP LIST(‘データ終了’);
END;
/ BUILTIN関数によるサイズ確認はデバッグの基本 /
/ STG関数で実際の確保サイズをチェックする癖をつけよう /
PUT SKIP LIST(‘RECORD SIZE: ‘ || STG(VSAM_RECORD));
/ 処理ロジック /
DO I = 1 TO 100;
/ … 処理 … /
END;
END PROCESS_DATA;
END BATCH_PROCESS;
4. ベテランからのアドバイス:どう使い分けるべきか?
現場での鉄則はこうだ。
1. 外部インタフェース(ファイル入出力、通信電文):
レイアウトが決まっているため、原則として`UNALIGNED`を使用する。パディングが混入すると、他システムとのデータ整合性が取れなくなる。
2. 内部演算用(一時的な作業領域):
計算回数が膨大なループ内での配列には、`ALIGNED`を検討する。わずかなメモリ増分よりも、CPUのキャッシュ効率や命令実行速度の方が重要な場面が多いからだ。
3. デバッグのヒント:
「なぜかフィールドの値が化ける」という時は、`STG`(Storage)関数を使って、定義した構造体のサイズとオフセットを確認してほしい。予想外のパディングが挿入されていないかを確認するのが、トラブル解決の近道だ。
まとめ
PL/Iにおいて`ALIGNED`と`UNALIGNED`を制御することは、単なるメモリ節約術ではない。それは、ハードウェアの特性を理解し、システム全体のパフォーマンスを設計者の掌中に収めるということだ。
「とりあえずデフォルトで」という思考停止を卒業し、データの性質に合わせて属性を使い分ける。この小さなこだわりが、長年安定して稼働する堅牢なバッチプログラムを生む礎となる。
君たちが書くその一行が、明日もメインフレームを力強く支えることを期待している。何かあればまたいつでも聞きに来てくれ。
