なぜ「アライメント」を気にする必要があるのか
メインフレームでPL/Iを扱う際、データ構造の定義で「ALIGNED」や「UNALIGNED」というキーワードを見かけたことはありませんか?これらは、メモリ上でデータがどのように配置されるかを決める重要な指定です。なぜこの設定が重要かというと、CPUがメモリ上のデータを読み込む際、「キリの良いアドレス」から読み込む方が圧倒的に効率が良いからです。この設定を正しく理解することで、プログラムの実行性能を最適化し、外部ファイルとのデータ整合性トラブルを防ぐことができます。
基礎知識:アライメントとは何か
コンピュータのCPUは、メモリからデータを読み込む際、例えば「4バイト境界(アドレスが4の倍数)」のような特定の境界を基準にアクセスします。これを「アライメント」と呼びます。
ALIGNEDを指定すると、コンパイラはデータが境界に合うように、間に隙間(パディング)を挿入します。逆にUNALIGNEDは、パディングを極力省き、メモリを詰め込んで使用します。メモリ節約にはUNALIGNEDが有利ですが、アクセス効率はALIGNEDの方が高くなります。
実装と解決策
記憶域クラスがSTATIC(静的)であれAUTO(動的、DSA内)であれ、この指定はデータの物理的なオフセット位置を左右します。特に注意すべきは、バイナリ形式の外部データとやり取りする場合です。古いコードで意図的に調整されたアライメントを現代のコンパイラの設定だけで最適化しようとすると、外部データと構造のズレが生じ、読み込みエラーの原因となります。
サンプルプログラム
以下のコードは、ALIGNEDとUNALIGNEDの定義例です。どのように配置が変わるかを意識して記述します。
/ アライメントの指定例 /
DCL 1 SAMPLE_DATA,
5 FIELD_A BIN(31) ALIGNED, / 4バイト境界に配置される /
5 FIELD_B CHAR(3) UNALIGNED; / パディングなしで詰めて配置される /
/ 動作確認用のコード /
PROCEDURE OPTIONS(MAIN);
/ ALIGNEDはCPUのロード効率を最大化する設計 /
DCL VAL_ALIGNED BIN(31) ALIGNED AUTO;
/ UNALIGNEDはメモリ領域を節約したい場合に有効 /
DCL VAL_UNALIGNED BIN(31) UNALIGNED AUTO;
VAL_ALIGNED = 100;
VAL_UNALIGNED = 200;
PUT SKIP LIST('ALIGNEDの値を設定しました');
PUT SKIP LIST('UNALIGNEDの値を設定しました');
END;
応用・注意点
現場で最も陥りやすいバグは、「構造体の再定義」や「外部ファイルとのマッピング」におけるズレです。特に、メインフレームの古いプログラムを現代のコンパイラでリコンパイルする際、デフォルトのアライメント設定が変更されているケースがあります。
回避策として:外部データとやり取りする構造体については、必ず明示的に「ALIGNED」または「UNALIGNED」を指定してください。また、COPYライブラリで定義を共有している場合、呼び出し元と呼び出し先でこの属性が一致していないと、データが化ける原因になります。性能を優先するのか、メモリ効率を優先するのか、あるいは外部仕様との整合性を優先するのかを明確にしてコーディングしましょう。

コメント