11

一部の CPU アーキテクチャは非境界整列アドレス アクセスをサポートしていないことを知っています (たとえば、ARM 4 より前の ARM アーキテクチャには、メモリ内のハーフワード オブジェクトにアクセスする命令がありませんでした)。また、そのアーキテクチャの一部のコンパイラ (GCC の一部のバージョンなど) は、位置合わせされていないアドレスを検出すると、一連のメモリ アクセスを使用するため、位置合わせされていないアクセスは開発者にとってほとんど透過的です (ウィリアムによる GCC の決定的なガイドを参照)。フォンハーゲン

しかし、コンパイラはアドレスがアラインされているかどうかをどのように認識しているのでしょうか? 結局、コンパイラが見ているのは仮想アドレス (実効アドレス、EA) です。プログラムが実行されると、EA は OS によって任意の物理アドレスにマップされる可能性があります。仮想アドレスがアラインされていても、物理アドレスがアラインされていない可能性がありますね。物理アドレスのアラインメントは、実際に重要であり、CPU アドレス行で転送されます。

コンパイラは物理アドレスをまったく認識していないため、変数のアドレスがアラインされているかどうかを知るにはどうすればよいでしょうか?

4

2 に答える 2

16

仮想アドレスは、物理アドレスだけにマップされるわけではありません。仮想メモリは、物理ページに整列された方法でマップされたページで提供されます。(通常は 4096 に合わせます)。

参照:仮想メモリとアラインメント - どのように因数分解するのですか?

于 2012-12-19T13:53:36.700 に答える
2

一部のマシンは「アラインされたアクセス」を主張するため、アラインメントはオブジェクト コードにとって非常に便利な属性ですが、最新のコンピューターでは、キャッシュ ラインがパフォーマンスに大きな影響を与えるため、コード/ループ/データ/ロックのキャッシュ アラインメントが必要になるためです。あなたのローカルフレンドリーなコンパイラ。

Virtally all the loaders in the world support loading of code at power-of-two aligned boundaries of some modest size and on up. (Assemblers and linkers support this too with various ALIGNMENT directives). Often linkers and loaders just align the first loaded value anyway to a well-known boundary size; OSes with virtual memory often provide a convenient boundary based on VM page size (ties to other answer).

So a compiler can essentially know what the alignment of its emitted code/data is. And by keeping track of how much code it has emitted, it can know what the alignment of any emitted value is. If it needs alignment, it can issue a linker directive, or for modest sizes, simply pad until the emitted amount of code is suitably aligned.

このため、ほとんどのコンパイラは、そうするように指示されない限り、パフォーマンスに実質的に影響を与える方法で、キャッシュ ライン (または他のアーキテクチャが課す) の境界を越えるような方法でコードやデータ構造を配置しないと確信できます。

于 2012-12-19T14:57:00.767 に答える