整列するようにメモリにアクセスすることの意味は理解していますが、なぜこれが必要なのかわかりません。たとえば、アドレスから1バイトにアクセスできるのに0x…1
、同じアドレスからハーフワード(2バイト)にアクセスできないのはなぜですか。
繰り返しになりますが、アドレスA
とサイズのオブジェクトがあるs
場合、アクセスが調整されることを理解していますA mod s = 0
。しかし、これがハードウェアレベルで重要である理由がわかりません。
整列するようにメモリにアクセスすることの意味は理解していますが、なぜこれが必要なのかわかりません。たとえば、アドレスから1バイトにアクセスできるのに0x…1
、同じアドレスからハーフワード(2バイト)にアクセスできないのはなぜですか。
繰り返しになりますが、アドレスA
とサイズのオブジェクトがあるs
場合、アクセスが調整されることを理解していますA mod s = 0
。しかし、これがハードウェアレベルで重要である理由がわかりません。
ハードウェアは複雑です。これは簡単な説明です。
典型的な最新のコンピューターには、32 ビットのデータ バスがあります。これは、CPU が実行する必要があるフェッチは、特定のメモリ アドレスの 32 ビットすべてをフェッチすることを意味します。データ バスは 32 ビット未満のものをフェッチできないため、最下位 2 つのアドレス ビットはアドレス バスでも使用されないため、RAM が8 ビットバイトではなく 32 ビットワードのシーケンスに編成されているかのようになります。 .
CPU が 1 バイトのフェッチを行うと、バス上の読み取りサイクルで 32 ビットがフェッチされ、CPU はそれらのビットのうち 24 ビットを破棄し、残りの 8 ビットを任意のレジスタにロードします。CPU が32 ビット境界に整列されていない32 ビット値をフェッチする場合、いくつかの一般的な選択肢があります。
私が使用したさまざまな CPU は、これら 4 つのパスすべてを採用しています。一般に、最大限の互換性を得るには、すべての n ビット読み取りを n ビット境界に揃えるのが最も安全です。ただし、ソフトウェアが特定の CPU ファミリで実行され、既知のアライメントされていない読み取り動作が行われることが確実な場合は、ショートカットを使用できます。また、アラインされていない読み取りが可能であっても (x86 ファミリーの CPU などで)、速度が低下します。
コンピューターは常に、位置合わせされた固定サイズのチャンクを読み取ります。
そのため、データをメモリ内で整列させないと、おそらく複数回読み取る必要があります。
例
つまり、基本的にはスピードアップです。
すべてのアライメント ルールの理由は、キャッシュ ラインのさまざまな幅にあります (命令キャッシュにはコア 2 アーキテクチャ用に 16 バイト ラインがあり、データ キャッシュには L1 用に 64 バイト ライン、L2 用に 128 バイト ラインがあります)。
そのため、Cahce-Line 境界を超えるデータを保存/ロードする場合は、両方のキャッシュ ラインをロードおよび保存する必要があり、パフォーマンスに影響します。したがって、パフォーマンスが低下するため、それを行うのは簡単です。
シリアルポートを読み取ってみてください。データは 8 ビット幅です。優れたハードウェア設計者は、それが単語の最下位バイトにあることを確認します。
ワード境界で整列されていない要素を持つ C 構造体がある場合 (下位互換性やメモリの節約などから)、構造内のバイトのアドレスはワード境界で整列されません。