エンディアン

バイト単位のメモリアクセスをサポートするコンピュータでは、アドレスの最小単位はバイトとなる。アクセス対象が1バイトの場合は問題ないが、2バイト以上の場合は、整数として最上位のバイトを最初のアドレスに格納する方式と、この逆に最下位のバイトを最初のアドレスに格納する方式があり得る。

Big EndianとLittle Endian。上位バイトを先に置くか、下位バイトを先に置くか?

図の上側は、最上位バイトをアドレスAに置き、下位のバイトをA+1、A+2、A+3番地に順に置く方式であり、Big Endian(ビッグ エンディアン)と呼ばれる。一方、数値的に最下位のバイトを最初のアドレスに置く方式はLittle Endian(リトル エンディアン)と呼ばれる。

Big Endianは、先頭アドレスの最上位ビットがMSB(Most Significant Bit)であり、右に行くにつれて重みが減少し、最後のアドレスの最下位ビットが整数全体のLSB(Least Significant bit)となり、直感的に理解しやすい表現方法である。IBMのSystem 360メインフレームではこのBig Endianが用いられており、PowerPCやSPARCなどでもBig Endianが採用されている。

Bit Endianの場合は、メモリとレジスタのバイトの重みが一致しており、メモリとレジスタの対応は次の図のようになる。

Big Endianの場合のメモリとレジスタの対応

一方、Little Endianの場合は、先ず、最下位のバイトをメモリから読み、最下位のバイト同士を加算して結果を格納し、キャリーを保存して、次のバイトをメモリから読んでキャリーを考慮して加算すると言う処理が可能であり、バイト単位で加算処理を行う場合には都合が良く、必要なハードウェアを減らせるということから、DECのミニコンではLittle Endianを採用し、それがx86アーキテクチャにも受け継がれている。Little Endianは、Big Endianとはメモリとレジスタのバイトの重みが逆であるが、次の図のようにメモリ内部のバイトの格納順を逆にしてやれば、Big Endianと同じ回路構成になる。

Little Endianの場合のメモリとレジスタの対応

ということで、どちらのEndianでも機能的には大差は無いのであるが、ディスクなどに書かれた計算結果がBig Endianであれば、それを読んで処理するのは、やはりBig Endianのコンピュータでないとバイト順の並べ替えが必要となるし、Little Endianの場合も同様で、書いたコンピュータと読むコンピュータのEndianが一致していないとやり難いということで、Big Endian族とLittle Endian族は互いに独立のテリトリを築いて生きてきた。

しかし、インターネット時代になると、インターネットプロトコルはBig Endianで定義されてしまったので、Little Endian族もBig Endianを無視できなくなり、また、x86アーキテクチャの隆盛から、データ交換のためには、Big Endian族もLittle Endianを無視できなくなるという状態になっている。このため、最近では、どちらのEndianのコンピュータも、基本のEndianは変更しないものの、データのロード、ストアに関しては両方のEndianをサポートするというのが一般的である。

データアライメント

メモリを無駄なく使おうという立場からは、4バイト長のデータでも任意のバイトアドレスからは格納できることが望ましい。上の図では、4バイト(32ビット)のデータは0番地、4番地、8番地、…のように4バイトの倍数から始まっているが、メモリのどのバイトもレジスタの最上位バイトになれるようにするには、次の図のようにレジスタ側のマルチプレクサに灰色の矢印で書いた入力を追加する必要がある。

4バイト長のデータが任意のバイト位置に格納できる構成

煩雑になるので、この図では、レジスタの最上位のバイトに対する追加パスだけを表示しているが、残りの3バイトについても、同様にパスを追加する必要がある。また、このように任意のアドレスから4バイトのデータアライメントを許すと、開始アドレスがA+5~A+7の場合は、後ろ側はA+8からの8バイトにまたがってしまい、メモリを2回読んで纏めるという複雑な処理が必要になり、性能も低下する。

ここではメモリとレジスタの間に8入力のマルチプレクサが入る図になっているが、最近のキャッシュを持つマイクロプロセサでは、レベル1のデータキャッシュとレジスタの間に、このマルチプレクサが入ることになる。マルチプレクサの入力が増えると、配線が増加してチップ面積が増えるし、遅延時間も増加しサイクルタイムに対するプレッシャーとなる。

一方、4バイトのデータは4バイトの倍数のアドレスにしか格納できないという制約を設けると、メモリの利用効率は低下するが、前の図のように、マルチプレクサの入力数を抑え、性能的にも有利になるというトレードオフが存在する。

このように、どのサイズのデータをどの先頭アドレスに格納できるかをデータアライメント、あるいは単純にアライメントという。本来、データアライメントと命令がCISCであるかRISCであるかは殆ど独立であるが、一般的に、メモリが高価な時代に作られたCISC命令アーキテクチャではどのサイズのデータでも任意のアドレスから格納できるという構成が多く、RISCではハードの簡単化を目指すという設計思想から、2バイトデータは2の倍数、4バイトデータは4の倍数のように、データのサイズの倍数の先頭アドレスにだけ格納できるという制約が付けられることが多い。このRISCのようなデータアライメントはナチュラルアライメントと呼ばれる。