導入
メインフレームにおいて、ディスク容量の節約は今も昔も重要なテーマです。特に大量のレコードを扱うバッチ処理では、データ構造のわずかな無駄がストレージコストやI/O負荷に直結します。今回は、PL/Iなどで利用される「UNALIGNED属性」を活用し、コンパイラが自動的に挿入する「パディング(詰め物)」を排除して、メモリとディスクを効率的に利用する技術を解説します。
基礎知識:なぜパディングが発生するのか
コンピュータのCPUは、メモリ上のデータを読み書きする際、データの境界(ワード境界など)が整っている方が高速に動作します。そのため、コンパイラはデフォルトで、変数の型に合わせて自動的に「隙間(パディング)」を挿入して境界を調整します。これを「ALIGNED(アライメント)」と呼びます。
例えば、1バイトの文字型の次に4バイトの整数型が来ると、整数型が4の倍数のアドレスから始まるよう、間に3バイトの無駄な領域が挿入されることがあります。このパディングを意図的に排除する指示子が「UNALIGNED」です。
実装・解決策
UNALIGNEDを指定すると、データは詰め込まれた状態でメモリに配置されます。これにより、レコード長を最小限に抑えることが可能です。特に、外部システムとのバイナリデータ交換や、ディスク上の物理レコードを直接定義する際には非常に有効です。
サンプルプログラム
以下は、パディングを排除してレコードを定義する具体的な例です。
DCL 1 TIGHT_REC UNALIGNED,
/ 1バイトの文字型 /
2 C1 CHAR(1),
/ 通常なら3バイトのパディングが入るが、UNALIGNEDにより直後に配置される /
2 B1 FIXED BIN(31);
/ データ確認用の簡易処理 /
PUT SKIP LIST(‘レコードサイズは: ‘, STG(TIGHT_REC), ‘ バイトです’);
応用・注意点
この技術を用いる上で、特に注意すべきは「他言語との連携」です。
1. バイナリ互換性の落とし穴
JavaやC言語など、他のプログラミング言語で同じデータ構造を定義する場合、デフォルトではアライメントが有効になっていることがほとんどです。UNALIGNEDで定義したメインフレーム側の構造体をそのまま外部システムで読み込もうとすると、バイト位置がずれて正しくパースできません。
2. 回避策
異機種間連携を行う場合は、以下のいずれかの対策を講じてください。
・相手側のデータ構造にも、パディングを排除するオプション(C言語なら #pragma pack(1) など)を適用する。
・構造体に手動でダミー変数(例:2 DUMMY CHAR(3);)を挿入し、構造を合わせる。
3. パフォーマンスの考慮
パディングを排除すると、一部のCPUアーキテクチャではデータアクセスの際に微細なオーバーヘッドが生じる可能性があります。しかし、近年のメインフレーム環境では、ディスクI/Oの削減によるメリットの方が遥かに大きいため、大規模なデータセットを扱う際には積極的に検討すべき手法です。
データ構造の「隙間」を意識することは、メインフレーム技術者としての腕の見せ所です。ぜひ、システムの要件に合わせて使い分けてみてください。

コメント