2017-05-04 9 views
2

4バイトの自然な整列を仮定します。キャッシュにロード中のデータの整列

struct Node 
{ 
int data; 
char c_data; 
}; 
int main() { 
int global = 10; 
struct Node N; 
for (register int i = 0; i < 10; i++) 
cout << global << N.data << endl; } 

キャッシュラインサイズが16バイトと私のプログラムは、ループ内でこれらの2つの変数にアクセスしている場合、どのようにこれらの変数がキャッシュに存在するであろうがある場合は?他のすべてがレジスタ変数であると仮定します。

同じキャッシュ行にありますか?

オン異なるキャッシュライン?

同じキャッシュラインの場合、各メンバーはキャッシュ内で4バイトのアライメントされたアドレスから開始しますか?グローバル変数のようなものは[0,3]からスパンし、Nは[4,7]のスパンになります。または、構造体にcharがあった場合は、キャッシュラインの[5]から開始することもできます。

基本的には、キャッシュにデータをロードする際に、構造体のサイズに基づいて配置が考慮されるか、最初のメンバーですか?

+0

データはデータサイズではなく、ラインサイズに基づいてキャッシュラインにロードされるため、メモリ内のデータ編成/アライメントはキャッシュに反映されます。 – LPs

答えて

2

キャッシュがどのように使用されるかは、主にコードに依存します。これは、あなたの質問で言及したが投稿しなかった理論上のループです。ループの前に使用される他の変数は、どこに割り当てられる変数に応じて優先されます。特定のシステムを念頭に置いた詳細なソースコードが与えられても、何が起きるかを正確に伝えることは非常に難しいです。

メモリに隣接して割り当てられる変数は、キャッシュに適しています。基本的には、キャッシュが効率的になるように、RAMからキャッシュに転送できる隣接して割り当てられた変数のチャンクが存在するはずです。変数が完全に異なるセグメントにある場合、「キャッシュミス」が発生します。つまり、何かがキャッシュから取り出されなければならず、何かがRAMから読み込まれる必要があります。

たとえば、スタックに割り当てられたローカル変数のチャンクがある場合、すべてがキャッシュに格納されることが有益な場合があります。あなたのケースでは

は、globalは、メモリの.dataセクションに割り当てられ、N.bssセクションに割り当てられているので、彼らは全く隣接していないと、その理由のために同じキャッシュラインにロードされません。あなたのケースでは、キャッシュディスカッション全体が適用されないことを意味します。

あなたの代わりにstruct Node N = {1};を書いていた場合、変数は、コード内の同じ場所で使用する場合には、(私は乱暴に推測しています).dataでこのように割り当てられて終わるだろうと考えるのが妥当と思われる:

4 bytes - global 
4 bytes - N.data 
4 bytes - N.c_data 

ここで、調整はCPUに合わせて調整されます。キャッシュはRAMをミラーリングするだけで、 "アライメントに合わせて移動する"ものはありません。RAMで変数が割り当てられた時点で、アライメントはすでに処理されています。

この全体のチャンクは、キャッシュに潜在的に読み込まれる可能性があります。

+0

あなたの答えに基づいて、グローバル変数とNをローカル変数として保持するように質問を修正しました。今、私の質問は、どちらかのグローバルアドレスかどうか、またはCachleline上のNが4の倍数のオフセットになるかどうかです。 0,4,8のように。または、キャッシュラインのオフセット3,5で開始できますか?私はここでアーキテクチャの知識が不足しているかもしれません。データがどのように引き込まれ、アライメントの観点からキャッシュに格納されるかについての案内をしてください。 –

+1

@AnupBuchkeコンパイラ/リンカがRAMの整列したアドレスにそれらを配置すると、変数は整列されます。キャッシュはRAMの同一コピーで、0〜_n_バイトのデータを格納します。 – Lundin

+0

ありがとうございました。それは役に立ちます。リンカーがそれらをRAMにどのように置くかを調べます。 –

関連する問題