質問

Pentium などの Intel の 32 ビット プロセッサは 64 ビット幅のデータ バスを備えているため、アクセスごとに 8 バイトをフェッチします。これに基づいて、これらのプロセッサがアドレス バス上で発行する物理アドレスは常に 8 の倍数であると仮定します。

まず、この結論は正しいでしょうか?

第 2 に、それが正しい場合は、データ構造メンバーを 8 バイト境界に配置する必要があります。しかし、これらのプロセッサでは代わりに 4 バイト アラインメントを使用している人を見たことがあります。

彼らがそうすることをどうやって正当化できるのでしょうか?

役に立ちましたか?

解決

(ストレートIntelのとAMDの最適化マニュアルからの)親指の通常のルールは、すべてのデータ型は、独自のサイズによって整列されなければならないということです。 int32はこれに32ビット境界、64ビット境界にint64上に整列し、すべきです。チャーはどこでもうまくフィットします。

親指のもう一つのルールは、もちろん「コンパイラは、アライメントの要件について言われている」されます。コンパイラは、データへの効率的なアクセスを許可するように右パディングとオフセットを追加するために知っているので、あなたはそれを心配する必要はありません。

手動でほとんどのコンパイラの整列を保証する必要がSIMD命令、で作業する場合、

唯一の例外はある。

  

第二に、それがある場合は、正しい、そして1   上のデータ構造体のメンバを揃える必要があります   8バイト境界。しかし、私は見てきました   4バイトのアライメントを使用している人々   代わりに、これらのプロセッサ上でます。

私はそれが違いをどのように表示されません。 CPUは、単にこれらの4つのバイトを含む64ビットのブロックの読み取りを発行することができます。つまり、要求されたデータの前に4つの余分なバイトを取得し、またはそれの後のいずれかを意味します。しかし、どちらの場合には、それだけで、単一の読み取りを取ります。 32ビット幅のデータの32ビットのアライメントは、64ビット境界と交差しないことを保証する。

他のヒント

物理バスは 64 ビット幅です ...8 の倍数 --> はい

ただし、考慮すべき要素がさらに 2 つあります。

  1. 一部の x86 命令セットはバイトアドレスで指定されます。一部は 32 ビットにアライメントされています (4 バイトのものがあるのはそのためです)。ただし、64 ビットにアライメントされている (コア) 命令はありません。CPU は、不整合なデータ アクセスを処理できます。
  2. パフォーマンスを重視する場合は、メイン メモリではなくキャッシュ ラインについて考慮する必要があります。キャッシュラインはさらに幅が広くなります。

これは8バイトアライメントに変更するとABIの変更を構成するであろうので、そうすることで正当化され、限界性能の向上は、トラブルの価値はありませんされています。

他の誰かがすでに述べたように、物質キャッシュライン。すべての実際のメモリバス上のアクセスは、キャッシュライン(x86の、IIRCに64バイト)の点です。すでに述べた「すべてのプログラマは、メモリについて知る必要があるもの」ドキュメントを参照してください。だから、実際のメモリトラフィックは64バイト整列されます。

ランダムアクセスの場合と限りデータは(例えば、境界を越える)ずれていないので、私はそれがはるかに重要とは思いません。正しいアドレスとデータのオフセットはシンプルで発見され、ハードウェアで構築することができます。 1は、アクセスが一つの値を取得するのに十分ではない読んだときには遅くなります。これらは特定のオフセットである必要はありませんので、コンパイラは通常、一緒に小さな値(バイトなど)を置く理由もあります。パンツは、偶数アドレスで、32ビットの8バイトのアドレスに4バイトのアドレスと64ビットにする必要があります。

あなたはキャッシングinvoledとリニア・データ・アクセスを持っている場合は、物事が異なることに注意してください。

64ビット・バスは、あなたはキャッシュをフィードを参照してください。 CPUとして、常に全体のキャッシュラインを読み書きします。キャッシュラインのサイズは常に8の倍数であり、その物理アドレスが実際に8つのバイトのオフセットで整列されます。

キャッシュ・ツー・レジスタの転送は、外部データバスを使用しないので、そのバスの幅は関係ありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top