3

非一時的な書き込みと書き込み結合手法については、次のコードがあります

void setbytes(char *p, int c)
{
__m128i i = _mm_set_epi8(c, c, c, c,
c, c, c, c,
c, c, c, c,
c, c, c, c);
_mm_stream_si128((__m128i *)&p[0], i);
_mm_stream_si128((__m128i *)&p[16], i);
_mm_stream_si128((__m128i *)&p[32], i);
_mm_stream_si128((__m128i *)&p[48], i);
}

ここから撮影

と書かれています

要約すると、このコード シーケンスは、書き込まれる前にキャッシュ ラインを読み取ることを回避するだけでなく、すぐには必要とされない可能性のあるデータでキャッシュを汚染することも回避します。これは、特定の状況で大きなメリットをもたらす可能性があります。

私の質問は次のとおりです。どのキャッシュラインが書き込まれるのを避けていますか? i 変数の内容を格納するキャッシュ ライン、または p ポインターが指すキャッシュ ライン (後で変更される) は?

4

2 に答える 2

4

about:「キャッシュラインが書き込まれる前に読み取ることを回避します」

このステートメントは、キャッシュにない書き込みを処理するための「書き込み割り当て」ポリシーを参照しています。最新の x86 プロセッサはすべてこれを行います。次のようになります。ソフトウェアは、通常の mov 命令を使用してメモリに書き込みます。そのアドレスが既にキャッシュされている場合、キャッシュが更新され、DRAM アクセスはまったくありません。ただし、データがキャッシュにない場合、プロセッサはそのキャッシュ ラインを DRAM から読み取ります。次に、mov 命令からのデータがキャッシュ内のデータにマージされます。プロセッサは、そのデータを DRAM に書き戻すのを可能な限り延期します。最終結果は直観に反します。ソフトウェアが書き込み (mov) 命令を実行し、単一の DRAM 読み取り (バースト) が結果として生じます。このパターンが繰り返されると、最終的にキャッシュがいっぱいになり、読み取り用のスペースを確保するためにエビクションが必要になります。その場合、関係のないキャッシュ ライン アドレスの DRAM 書き込みバーストが発生し、ソフトウェアが書き込み中のアドレスが読み取られます。これは、非テンポラル ストアが大きなバッファを埋めるために約 2 倍のパフォーマンスを提供する理由を説明しています。mov を使用してバッファを埋める場合と比較すると、発生する DRAM アクセスの数は半分になります。

于 2013-03-25T05:36:53.550 に答える
1

宛先のアドレスがまだキャッシュにない場合、ストリーミングはキャッシュの汚染を防ぎます。それ以外の場合は、必要に応じて、そのキャッシュラインによってバックアップされたアドレスに書き込まれた新しい値でキャッシュを更新します。

したがって、あなたの例では、読み取りを行っていない場合p(またはキャッシュからフラッシュした場合)、ストリーミングストアは、ポイントが指すアドレスのキャッシュにポイントがロードされるCLFLUSH場所にデータが書き込まれるのを防ぎます(つまり: no書き込まれたアドレスに対してキャッシュラインが作成されます)。pp

于 2013-03-22T20:07:55.000 に答える