各データ型は、バイト数の倍数に整列する必要があります。たとえば、short int
は2バイトの倍数にアラインする必要があり、int
は4バイトの倍数にアラインする必要があります。
しかし、データアライメントが正確に使用されるのは、CPUがメモリから読み取ることができるのは、ある数の倍数に限られるためです。たとえば、CPUがshort int
、アドレス0、2、4、6などからのみ読み取ることができますか?
基本的にそうです。 CPUがアライメントされていないアドレスでメモリを読み取ることは可能ですが、時間がかかります。これはおそらく単純化ですが、次のように機能します。
通常、RAMコントローラからCPUに向かうデータラインのセットがあります。たとえば、64ビットプロセッサを使用している場合、RAMコントローラはCPUに接続します。RAMコントローラは常に64ビット(8バイト)をRAMから引き出し、データに沿って送信しますCPUへの行。CPUは必要なものをマスクして、残りを破棄する必要があります。
ただし、落とし穴があります。メモリコントローラーは、どのアドレスから読み取るかをCPUに指示する必要があります。したがって、CPUからメモリコントローラーに向かうアドレスラインがあります。メモリコントローラーを簡素化するために、常に8バイト境界で境界から読み取ります。回路は、私が理解しているように(ハードウェアエンジニアではありませんが)、どのアドレスからでも読み取るにははるかに複雑にする必要があります。
したがって、8バイト境界以外のアドレスでメモリを読み取る場合、CPUは必要な最下位バイトのアドレスを送信し、メモリコントローラは3つの下位ビットをマスクして8バイトを読み取り、それらをCPUに送り返します。 。 8バイトの境界を越えた場合、メモリコントローラーは次の8バイトの範囲を読み取って送り返す必要もあります。次に、CPUは各読み取りから正しいバイト数をマスクして、それらをシフトし、それらを結合して1つの8バイト数に戻す必要があります。 (または、おそらくそれがすべてメモリコントローラーで発生しますか?どちらにしても時間がかかります。)
8バイトを読み取っていない場合でも、奇数アドレスから読み取る場合は、結果をマスクしてシフトしてレジスタに格納する必要があります。
一部の古いローエンドCPUは、一部のアライメントされた読み取りでもこれを行いました。たとえば、8088には8本のデータラインしかなかったと思うので、16ビットの読み取りでは常に2回の読み取りが行われ、メモリフェッチのサイクル数は2倍になります。ただし、データがCPU上にあると、8086と同じ速さで処理されました。
コメントで述べたように、おそらくは設計を簡素化してコストを下げるために、非整列読み取りを実行できないCPUもあります。