16

これが何度も回答されていると思われる場合はご容赦ください。ただし、次の質問に対する回答が必要です。

  1. なぜデータを (2 バイト / 4 バイト / 8 バイト境界で) 揃える必要があるのですか? ここで私の疑問は、CPU にアドレス ライン Ax Ax-1 Ax-2 ... A2 A1 A0 がある場合、メモリ位置を順番にアドレス指定することがかなり可能であるということです。では、なぜ特定の境界でデータを揃える必要があるのでしょうか?

  2. コードをコンパイルして実行可能ファイルを生成するときにアライメント要件を見つけるにはどうすればよいですか?

  3. たとえば、データ アライメントが 4 バイト境界である場合、連続する各バイトがモジュロ 4 オフセットに配置されていることを意味しますか? 私の疑問は、データが 4 バイトにアラインされている場合、それはバイトが 1004 にある場合、次のバイトが 1008 (または 1005) にあるということですか?

4

7 に答える 7

16

CPU はワード指向であり、バイト指向ではありません。単純な CPU では、メモリは通常、アドレス ストローブごとに1ワード(32 ビット、64 ビットなど) を返すように構成されます。下の 2 つ (またはそれ以上) のアドレス ラインは一般にドントケア ビットです。

Intel CPU は多くの命令の非ワード境界でアクセスを実行できますが、CPU は内部で 2 つのメモリ アクセスと 1 つのワードをロードするための演算操作を実行するため、パフォーマンスが低下します。バイト読み取りを行う場合、アライメントは適用されません。

一部の CPU (ARM、または Intel SSE 命令) は、アラインされたメモリを必要とし、アラインされていないアクセスを実行する (または例外をスローする) ときに未定義の操作を行います。はるかに複雑なロード/ストア サブシステムを実装しないため、シリコン スペースを大幅に節約できます。

アラインメントは、CPU ワード サイズ (16、32、64 ビット) に依存するか、SSE の場合は SSE レジスタ サイズ (128 ビット) に依存します。

最後の質問については、一度に 1 つのデータ バイトをロードする場合、ほとんどの CPU にアラインメントの制限はありません (一部の DSP にはバイト レベルの命令がありませんが、実行されることはないでしょう)。

于 2010-06-11T18:21:04.187 に答える
6

整列する必要があるデータはほとんどありません。特定のタイプのデータのパフォーマンスが向上する場合や、特定の CPU 操作で特定のデータの配置が必要になる場合があります。

まず、一度に 4 バイトのデータを読み取るとします。また、CPU に 32 ビットのデータ バスがあるとしましょう。また、データがシステム メモリのバイト 2 に格納されているとします。

一度に 4 バイトのデータをロードできるため、アドレス レジスタが 1 バイトを指すようにしてもあまり意味がありません。アドレス レジスタを 4 バイトごとに指定することで、4 倍のデータを操作できます。つまり、CPU はバイト 0、4、8、12、16 などから始まるデータしか読み取れない可能性があります。

それでは本題です。バイト 2 から始まるデータが必要で、4 バイトを読み取っている場合、データの半分はアドレス位置 0 にあり、残りの半分は位置 1 にあります。

したがって、基本的には、1 つの 4 バイト データ要素を読み取るためにメモリを 2 回ヒットすることになります。一部の CPU は、この種の操作をサポートしていません (または、2 つの結果を手動で読み込んで結合する必要があります)。

詳細については、http: //en.wikipedia.org/wiki/Data_structure_alignmentを参照してください。

于 2010-06-11T18:22:00.580 に答える
4

1.)一部のアーキテクチャにはこの要件がまったくなく、一部のアーキテクチャではアライメントが推奨され(非アライメントのデータ項目にアクセスすると速度が低下します)、一部のアーキテクチャでは厳密に強制される場合があります(ミスアライメントによりプロセッサ例外が発生します)。
今日人気のあるアーキテクチャの多くは、速度ペナルティのカテゴリに分類されます。CPU設計者は、柔軟性/パフォーマンスとコスト(シリコン領域/バスサイクルに必要な制御信号の数)の間でトレードを行う必要がありました。

2.)どの言語、どのアーキテクチャですか?コンパイラのマニュアルやCPUアーキテクチャのドキュメントを参照してください。

3.)これも完全にアーキテクチャに依存します(一部のアーキテクチャでは、バイトサイズのアイテムへのアクセスがまったく許可されていないか、バス幅が8ビットの倍数でもない場合があります)。したがって、特定のアーキテクチャについて質問しない限り、有用な回答は得られません。

于 2010-06-11T18:28:38.367 に答える
2

一般に、これら 3 つの質問すべてに対する 1 つの答えは、「システムによって異なります」です。詳細:

  1. メモリ システムがバイト アドレス指定可能でない場合があります。それに加えて、プロセッサがアラインされていないデータにアクセスすると、パフォーマンスが低下する可能性があります。一部のプロセッサ (たとえば、古い ARM チップなど) はまったく実行できません。

  2. プロセッサのマニュアルと、コードが生成されている ABI 仕様を読んでください。

  3. 通常、データが特定のアラインメントにあると言及する場合、それは最初のバイトのみを指します。したがって、ABI 仕様で「データ構造 X は 4 バイトでアラインされている必要がある」と記述されている場合、X はメモリ内の 4 で割り切れるアドレスに配置する必要があることを意味します。構造 X のサイズや内部レイアウトについて、その記述によって暗示されるものは何もありません。 .

    特定の例に関する限り、データがアドレス 1004 から始まる 4 バイトで整列されている場合、次のバイトは 1005 になります。

于 2010-06-11T18:18:21.303 に答える
2

使用している CPU に完全に依存します。

一部のアーキテクチャは 32 (または 36!) ビット ワードのみを処理し、1 文字または 1/2 ワードをロードするには特別な命令が必要です。

一部の CPU (特に PowerPC やその他の IBM RISC チップ) はアラインメントを気にせず、奇数アドレスから整数をロードします。

最近のほとんどのアーキテクチャでは、整数をワード境界に、long 整数をダブルワード境界に揃える必要があります。これにより、レジスタをロードするための回路が簡素化され、速度がわずかに向上します。

于 2010-10-11T01:54:53.187 に答える
1

パフォーマンス上の理由から、CPU ではデータの整列が必要です。Intel の Web サイトでは、メモリ内のデータを整列する方法について詳しく説明しています。

64 ビット インテル® アーキテクチャーに移行する際のデータ アライメント

これらの 1 つは、データ項目の位置合わせです。つまり、4、8、または 16 バイトの倍数であるアドレスに関連するメモリ内の位置です。16 ビットの Intel アーキテクチャでは、データ アライメントはパフォーマンスにほとんど影響を与えず、その使用は完全にオプションでした。IA-32 の下では、データを正しく配置することは重要な最適化になる可能性がありますが、正しい配置が必須である非常に少数の例外を除いて、その使用は依然としてオプションです。ただし、64 ビット環境では、データ項目に対してより厳しい要件が課されます。位置合わせされていないオブジェクトは、プログラムの例外を引き起こします。項目を適切に配置するには、64 ビット Intel アーキテクチャ (後で説明) によって課される要件と、アプリケーションのビルドに使用されるリンカーの要件を満たす必要があります。

データ整列の基本的なルールは、最も安全な (そして最も広くサポートされている) アプローチは、Intel が「自然境界」と呼んでいるものに依存するということです。これらは、データ項目のサイズを 2 バイト、4 バイト、8 バイト、または 16 バイトの次に大きいサイズに切り上げるときに発生するものです。たとえば、10 バイトの float は 16 バイトのアドレスに配置する必要がありますが、64 ビットの整数は 8 バイトのアドレスに配置する必要があります。これは 64 ビット アーキテクチャであるため、ポインターのサイズはすべて 8 バイト幅であり、それらも 8 バイト境界に揃える必要があります。

16 バイトより大きいすべての構造体は、16 バイト境界に揃えることをお勧めします。一般に、最高のパフォーマンスを得るには、次のようにデータを調整します。

  • 任意のアドレスで 8 ビット データを整列
  • アライメントされた 4 バイト ワード内に含まれる 16 ビット データをアライメントします。
  • ベース アドレスが 4 の倍数になるように 32 ビット データを整列します。
  • ベース アドレスが 8 の倍数になるように 64 ビット データを整列する
  • ベース アドレスが 16 の倍数になるように 80 ビット データを整列する
  • ベース アドレスが 16 の倍数になるように 128 ビット データを整列する

64 バイト以上のデータ構造または配列は、そのベース アドレスが 64 の倍数になるように位置合わせする必要があります。サイズの小さい順にデータを並べ替えるのは、自然な位置合わせを支援する 1 つのヒューリスティックです。16 バイトの境界 (およびキャッシュ ライン) を超えない限り、自然なアライメントは厳密には必要ありませんが、一般的なアライメントの推奨事項を順守するための簡単な方法です。

構造内でデータを正しく配置すると、(フィールドを正しく配置するために必要なパディングが原因で) データが肥大化する可能性があるため、必要かつ可能な場合は、最も広い配置を必要とするフィールドが構造の最初になるように構造を再編成すると便利です。この問題の解決方法の詳細については、記事「IA-64 アーキテクチャ用のコードの準備 (コード クリーン)」を参照してください。

于 2013-08-18T00:57:59.893 に答える