6

私は C# で作業しておりunsafe、可能であればコードを避けたいと考えています。キャッシュ ラインを満たすサイズのオブジェクトまたは配列があり、オブジェクトのすべてのフィールドまたは配列のインデックスに書き込みたい場合、CPU は書き込み先のラインをフラッシュする前にすべての書き込みが発生するのを待つか、または書き込みが 1 回または数回しか発生していない場合、早期にフラッシュされますか?

ラインへのすべての書き込みが発生したときにのみフラッシュを発生させたい場合、ルーチンの最後にすべての書き込みを立て続けに行う必要がありますか? 私は、CPU とキャッシュ コヒーレンス プロトコルがこれに関して異なる可能性があることを知っています。一般的に真の経験則の答えを探しています。

4

2 に答える 2

2

CPU は書き込み先の行をフラッシュする前にすべての書き込みが発生するのを待ちますか、それとも 1 つまたは少数の書き込みのみが発生したときに早期にフラッシュしますか?

CPU はラインを早期にフラッシュする可能性がありますが、そのセットがキャッシュに属する他のアクセスからの圧力が高い場合に限られます。それはありそうもありません。キャッシュは、最近アクセスされたデータが時期尚早にフラッシュされるのを回避できるように構造化されています。

ルーチンの最後にすべての書き込みを立て続けに行う必要がありますか?

一般的にはい。 一時的な局所性は重要です。つまり、キャッシュは、アクセスが時間的に密接にグループ化されている場合に最適に機能します。他のトリックも同様に適用される場合があります。たとえば、必要な書き込みの前に構造体にダミーの書き込みを行うことで、キャッシュ ラインを「ウォーム」することができます。これにより、介在するコードの実行中にコアがキャッシュ ラインをロードするメモリ レベルの並列処理が可能になります。実際の書き込みを実行するまでに、L1 でキャッシュ ラインの準備が整う可能性が高くなります。

一般に、キャッシュのパフォーマンスを向上させるために、コード内の不自然な行為には十分注意してください。 キャッシュは、自分自身に任せるだけでかなり良い仕事をします。変更の前後に常にパフォーマンスを測定する必要があります。あなたが改善できると思っていることは、実際には害を及ぼす可能性があります。プログラムがマルチスレッドの場合、別の大きなワームが発生し、コア間のキャッシュ競合が発生します。

于 2013-02-22T17:13:02.103 に答える
1

当然、CPUは可能な限り少ないメモリアクセスを試みますが、それは必ずしもメモリの「あなたの」ブロックがあなたが望む限りキャッシュに保持されることを意味するわけではありません。

通常、メモリブロックは1回の読み取りと書き込みが行われますが、その保証はありません。コードを中断する何かが発生する可能性があり、システムは他の何かのためのスペースを作るためにそのキャッシュラインをフラッシュすることを決定する可能性があります。メモリ領域全体がメモリから完全に削除されてディスクにフラッシュされることもあります。そのため、コードが続行されると、ページフォールトが発生し、メモリが再度ロードされます。

もちろん、書き込みを時間的に近づけると、その操作の間、メモリがキャッシュに保持される可能性が高くなります。

于 2013-02-22T16:52:51.550 に答える