前のテキストに書いたように、コンピュータで扱うデータのサイズは 1 byte が最小単位となっています。
それらのデータはメモリに記録されて CPU/GPU などから利用されますので、CPU/GPU のメモリへのアクセス効率を上げるためにメモリの中も一般的に 1 byte ( = 8 bit) 単位でブロック分割されています(※)。
※ 必ずしも 8 bit である必要はなくて、PICマイコン上のメモリなどは13bitとか14bit単位でブロック分割されています。
例えばあるコンピュータが 8 byte のメモリを持っているとします。
するとそのメモリは 8 個のブロックに分けられ、1 byte のデータを 8 個保存することが出来るようになります(図1)。
図1: 8 byte メモリの構造
1 byte | 1 byte | 1 byte | 1 byte | 1 byte | 1 byte | 1 byte | 1 byte |
ここでサイズが 1 byte のデータ A、B、C をこのメモリに記録してみることにします。
それぞれのデータはこのメモリ内のどこかのブロックに記録される訳ですが、原則的にはどのブロックにデータを置いても良いので(※)、今回は図2のように A、B、Cを配置することにします。
※ 実際には色々ルールがあるので適当に配置出来る訳ではありません。
図2: 1 byte データを 3 つ記録する例
A | C | B |
この場合データ A、B、C の間に空のブロックが入っている上に(※)、A→B→Cと連続的に配置されている訳でないので、CPU/GPUが各データにアクセスしたくてもどうやってアクセスすれば良いのか困ってしまいます。
※ この様にデータとデータの間に複数の空ブロックが入っているとメモリの使用効率が落ちます。 これを「メモリ・フラグメンテーション」とか「メモリの断片化」と呼びます。
そこで各ブロックに「アドレス」と呼ばれる16進数の住所をつけて、アドレスを指定することで CPU/GPU が各データにアクセス出来るようにします(図3)。
図3の様に、「アドレス」+「ブロック」でメモリを表しているイメージを「メモリ空間」とか「アドレス空間」と呼びます。
図3: アドレス + ブロック = メモリ空間 (アドレス空間)
0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
A | C | B |
なおアドレスの単位は実社会でも使われている「番地」で、通常は「0x00 番地」からアドレスがブロックに割り振られます。
例えば図3の場合、CPU/GPU がデータ C にアクセスしたいなと思ったら、「0x03 番地」にアクセスすれば良いわけです。
また、データサイズが 1 byte ではなくて多 byte である場合は、データが 1 byte 毎に分割されてブロックに記録されます。
例えば図3 からデータ B と C を消して、代わりに図4 の様に 2 byte のデータ D と 3 byte のデータ E を記録出来ます(※)。
するとデータDのアドレスは「0x02 番地」、データEのアドレスは「0x05 番地」となります。
※ 図 4 の状況では空ブロックが不連続で 2 つ残っているので 1 byte のデータはあと 2 個保存出来ますが、2 byte のデータは記録出来ないことに注意して下さい。これが上の※で書いたメモリ・フラグメンテーションの例です。
図4: 多 byte のデータは 1 byte 毎に分割されて記録される
0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
A | D | E |