5

メモリアラインメントの概念について少し混乱しています。だからここに私の疑問があります:テキストが言うことは、4で割り切れないアドレスから始まる4バイトのデータを読みたい場合、アライメントされていないメモリアクセスの場合があるということです。たとえば、アドレス 05 から始まる 10 バイトを読み取りたい場合、これは非整列アクセス (http://www.mjmwired.net/kernel/Documentation/unaligned-memory-access.txt) と呼ばれます。

このケースは 4 バイト ワード アドレス指定可能アーキテクチャに固有のものですか、それともバイト アドレス指定可能アーキテクチャでも有効ですか? 上記のケースがバイト アドレス指定可能なアーキテクチャに対して整列されていない場合、なぜそうなるのでしょうか?

ありがとう!

4

2 に答える 2

4

原則として、メモリのビット 0 はバスにゲートされ、そのバスのビット 0 はすべてのレジスタのビット 0 に接続されます。これはビット 31 まで続きます。各バイト (ビット 15:8、23:16、および 31:24) を下位バイトのビット 7:0 に転送する特別なハードウェアがある場合があります。(ビット「32」に到達すると、実際にはアドレス 4 の 4 バイト ワードのビット 0 になります。)

ただし、公称の場合、自然な順序でバイトが接続されている位置以外の位置にバイトを移動する特別なハードウェアはなく、おそらくバイトレーン 0 もありません。

32 本のデータ ピンを備えた単純なメモリ チップと、32 本のデータ ピンを備えた単純な CPU を想像してみてください。各チップの特定のデータピンは、他のチップの対応するピンに配線され、そのピンのみに配線されます。単純な CPU が位置合わせされていない読み取りを行う方法はまったくありません

では、0 からの読み取りを考えてみましょう。次の 4 バイトはすべて有線としてレジスタに格納されます。これは、アドレス 4 からの読み取りでも発生します。しかし、アドレス 1 から (32 ビット) を読み取った場合はどうなるでしょうか? それとも2?それとも3?読み取りはハードウェアで直接行うことはできませんが、派手なコントローラーを使用すると、さまざまなことが発生する可能性があります。

  • CPU は、すべてのビットを取得するためだけに 2 回の読み取りを実行できます。同時に行うことはできません。ピンは 32 個しかありません。1 回の読み取りはアドレス 0 から、もう 1 回はアドレス 4 からです。
  • 次に、CPU は、2 つのコンポーネントから 1 つの単語を構築するために、さまざまなシフト、マスク、および包括的 OR 操作を実行する必要があります。

これらはすべて余分な時間がかかります。


ノート。実際には、データ バスは通常 32 ビットの倍数であり、メモリも同様です。オブジェクトを再配置するための特別なハードウェアが存在する場合があります。しかし、それでも、異常なケースであるため、適切に整列された読み取りが取得するパイプラインの最適化を取得できない可能性があり、特別なハードウェアを使用しても、オペランドを実行するための時間のペナルティが発生する可能性があります。

于 2012-04-05T01:31:39.770 に答える
2

アラインメントは、データのサイズとアドレス指定に関係しています。ほとんどの命令セット/ソフトウェアのアドレス指定はバイト単位です。0、1、2、3 はすべて有効なバイト アドレスです。アクセスしているメモリシステムまたは周辺機器が「バイトアドレス指定可能」であると仮定すると、基本的に個々のバイトを書き込むことができ、通常は任意のアドレス値を使用できる命令があります。アライメントは、1 バイト、2 バイトを超えると開始されます。アライメントされている場合は、アドレスの lsbit が 0 であり、アライメントされていない場合は、1 であることを意味します。4 バイト、32 ビット量、下位 2 ビットが 0、整列、1 つまたは両方が 0 でない、整列されていない、など。モジュロ 4 = 0 が 4 バイト境界に整列するアドレスが必要なモジュロと考えることができます。

通常、ソフトウェア エンジニアとして、アドレス 5 で 10 バイトを取得する必要がある状況に意図的に身を置くことはありません。おそらく、10 しか使用しない場合でも、0x4 で 12 バイト、0x0 で 16 バイト、またはこれらの行に沿って何かを行うでしょう。それらのうち、より論理的に整列します。外部の影響、ネットワーク パケット、ファイル システム、共有メモリ、ハードウェアなど、コンパイル ドメインをまたぐときはいつでも、これに対処し、それに応じて行動しなければならない場合があります。10バイトは、これらのバイトを別の同等に悪いアドレスにコピーしようとしているか、単に読み書きするかによって異なります。読み取る場合は、おそらくアドレス 0x4 で 12 バイトを読み取って、それで完了したいだけです。適切に書き込めば、10 個すべてをナイス ループで実行するか、一度に 1 バイトずつ展開できます。0x5 に 1 つ、0x6 に 2 つ、0x8 に 4 つ、0xC に 2 つ、0xE に 1 つを書き込むことができます。または 0x5 に 1 つ、ループまたはアンロールされた 4 つの 16 ビット値が 0x6 で始まり、次に 0xE で 1 バイト。等。

読み取りと言ったので、0x4 で 3 つの 32 ビット量を読み取るか、0x0 から始まる 2 つの 64 ビット量を読み取ることができます。それは、データをどうするつもりか、どの命令セットを使用しているかなどに大きく依存します。

整列と非整列について疑問がある場合は、上記の書き込みで述べたように、次のことを行うことができます

8 bit access at 0x5
16 bit access at 0x6
32 bit access at 0x8
16 bit access at 0xC
8 bit access at 0xE

ただし、最も効率的ではない可能性のある読み取りについては、私が言い続けているように。書き込みの場合、32 ビットまたは 64 ビットの量、または上記の組み合わせで書き込みを読み取り変更できます。

于 2012-04-05T01:17:23.967 に答える