データ構造アライメント
第1のステップは、上位および下位のメモリワードを別々のレジスタにロードすることである。第2のステップは、MIPS命令と同様の特別なロー/ハイ命令を使用してメモリワードを抽出または修正することである。アラインされていないストアは、変更されたメモリワードをメモリに戻すことによって完了される。この複雑さの理由は、オリジナルのAlphaアーキテクチャでは、32ビットまたは64ビットの値しか読み書きできないためである。これは、しばしばコードが膨らんでパフォーマンスが低下する重大な制限となることが判明した。この制限に対処するために、元のアーキテクチャにByte Word Extensions (BWX) という拡張機能が追加された。これは、バイトとワードのロード・ストアのための命令で構成されている。
これらの命令は、通常のメモリロード・ストア命令よりも大きく、遅いため、必要なときにのみ使用するべきである。CおよびC++のコンパイラの中には、アライメントの合っていない命令を必要とするポインタに適用できる“unaligned”属性がある。
構造体のメンバは、メモリに順番に格納されるため、以下の構造体では、メンバData1は常にData2の前に、Data2は常にData3の前に配置される。
short型が2バイトのメモリに格納されている場合、上記の構造体の各メンバは2バイトでアラインされる。Data1はオフセット0、Data2はオフセット2、Data3はオフセット4になる。この構造体のサイズは6バイトになる。
構造体の各メンバの型は通常、デフォルトのアライメントを持つ。つまり、プログラマから別途要求されない限り、あらかじめ決められた境界にアラインされる。次の典型的なアライメントは、Microsoft (Visual C++)、Borland/CodeGear (C++ Builder)、Digital Mars (DMC)、GNU (GCC) で32ビットx86用にコンパイルする場合のものである。
char(1バイト) - 1バイトアライメント
short (2バイト) - 2バイトアライメント
int(4バイト) - 4バイトアライメント
long(4バイト) - 4バイトアライメント
float(4バイト) - 4バイトアライメント
double(8バイト) - Windowsでは8バイトアライメント。Linuxでは4バイトアライメント(コンパイル時に-malign-doubleオプションをつけると8バイト)
long long(8バイト) - 4バイトアライメント
コンピュータは一度に1つのメモリワードでメモリにアクセスする。メモリワードサイズが、コンピュータによってサポートされる最大のプリミティブ型と少なくとも同じ大きさである限り、アラインされたアクセスは常に1つのメモリワードにアクセスする。これは、アラインされていないデータアクセスに対しては当てはまらない。
データの最上位および最下位バイトが同じメモリワード内にない場合、コンピュータはデータアクセスを複数のメモリアクセスに分割する必要がある。これには、メモリアクセスを生成してそれらを調整するために、多くの複雑な回路が必要となる。メモリワードが異なるメモリページにあるケースを処理するために、プロセッサは、命令を実行する前に両方のページが存在することを検証するか、命令実行中にメモリアクセスでTLBミスやページフォールトを処理できる必要がある。
単一のメモリワードにアクセスするとき、その動作はアトミックである。すなわち、メモリワード全体が一度に読み書きされ、その処理が完了するまでは他のデバイスによるアクセスはできない。これは、複数のメモリワードへのアライメントされていないアクセスの場合は当てはまらない。例えば、あるデバイスが最初のワードを読み込み、別のデバイスが両方のワードに書き込み、その後、1つ目のデバイスが2つ目のワードを読み込んだとき、読み込まれた値は更新前の値とも更新後の値とも異なる。このような失敗はまれだが、識別するのが非常に難しい場合がある。
アラインされていないアクセスをサポートする利点は、アクセスを遅くするという犠牲を払ってでも、メモリを調整する必要のないコンパイラを書くほうが簡単だということである。生のパフォーマンスを最大にするように設計されたRISCプロセッサのパフォーマンスを向上させる1つの方法は、データの自然な境界にデータをロードまたは格納することである。従って、メモリは一般に8ビットのバイトで扱われるが、32ビットマシンで32ビット整数をロードするには32ビットごとに開始し、64ビットマシンで64ビット整数や浮動小数点数をロードするには64ビットごとに開始する必要がある。このような境界にない数値をロードするように要求された場合、プロセッサはフォールトにフラグを立てることができる。しかし、これは、どのワードがデータを含んでいるか把握し、同等の値を抽出する必要があるルーチンへの呼び出しを遅くすることになる。