導入
メインフレームでの開発において、データ構造の定義は単に領域を確保するだけではありません。特に数値演算を多用するプログラムにおいて、パフォーマンスを最大化するためには「メモリアライメント」を意識したデータ宣言が不可欠です。本稿では、PL/IにおけるALIGNED属性の役割と、それがなぜ重要なのか、そして実務で陥りやすい落とし穴について解説します。
基礎知識
メインフレームのCPUは、メモリ上のデータを「境界(バウンダリ)」に合わせた状態で読み出すときに最も効率良く動作します。例えば、フルワード(4バイト)境界であれば、アドレスが4の倍数である必要があります。
ALIGNED属性を指定すると、コンパイラは変数の開始アドレスがそのデータ型の境界に一致するように自動調整します。一方、UNALIGNED属性を指定すると、境界を無視して詰め込まれるためメモリ消費は抑えられますが、CPUがデータを取り出す際に余計な処理(複数回のメモリアクセスやシフト演算)が発生し、処理速度が低下する可能性があります。
実装/解決策
数値計算が主体の変数は、原則としてALIGNEDを指定するのが鉄則です。特にFIXED BINARY(31)やFLOATなどは、ALIGNEDを付与することでハードウェアの命令セットが最大限に活用されます。
定義の際は、構造体全体の整合性にも注意が必要です。構造体の一部にUNALIGNEDが混在すると、予期せぬパディング(空き領域)が発生し、構造体全体のサイズが変わる可能性があります。外部システムとのバイナリ連携を行う場合は、送信側と受信側でこのパディングの有無を完全に一致させる必要があります。
サンプルプログラム
以下は、計算速度を重視した変数定義と、パディングの考慮が必要な構造体定義のサンプルです。
/ 演算用変数の定義 /
DCL CALCULATED_VAL FIXED BIN(31) ALIGNED; / 演算効率を最適化 /
/ 外部通信用構造体の定義 /
DCL 1 COMM_RECORD,
5 HEADER_ID CHAR(4),
5 DATA_VAL FIXED BIN(31) ALIGNED, / 4バイト境界に配置される /
5 STATUS_FLG CHAR(1) UNALIGNED; / 後続のパディングを意識 /
/ 上記の構造体では、DATA_VALの後にパディングが発生する可能性があります /
/ 外部システムとのレイアウト合わせが必要な場合は、ダミー項目で明示的に埋めるのが安全です /
応用・注意点
現場で最も注意すべきは、「Java(JNI)やC言語とのデータ連携」です。現代の高級言語はメモリアライメントを自動管理しますが、そのルールはメインフレームのPL/IやCOBOLの解釈と必ずしも一致しません。
1. パディングの差異: C言語の構造体パディング規則と、PL/IのALIGNED属性による配置が食い違うと、データの読み取り位置がずれて破損の原因となります。
2. デバッグのヒント: 構造体のサイズが想定より大きい場合、それはコンパイラによって挿入されたパディングのせいです。SIZEOF関数やSTORAGE関数を使用して、実行時のオフセットを確認する癖をつけましょう。
3. 推奨事項: パフォーマンスがボトルネックとなっていない限り、構造体全体でアライメント方針を統一することをお勧めします。混在させると、デバッグ時に「どの変数がどのバイト位置にあるか」を計算するのが非常に困難になるためです。

コメント