12

キャッシュコヒーレンシを提供するx86のようなCPUでは、これは実用的な観点からどのように役立ちますか?1つのコアで行われたメモリの更新を、他のすべてのコアですぐに表示できるようにするという考え方を理解しています。これは便利なプロパティです。ただし、コンパイラは変数の割り当てをレジスタに格納し、それらをメモリに書き込むことはできないため、アセンブリ言語で記述しない場合は、これに大きく依存することはできません。これは、他のスレッドで行われたことが現在のスレッドで表示されるようにするために、明示的な手順を実行する必要があることを意味します。したがって、実用的な観点から、キャッシュコヒーレンシは何を達成しましたか?

4

6 に答える 6

10

簡単に言うと、非キャッシュコヒーレントシステムは、特に効率を維持したい場合、プログラミングが非常に困難です。これは、今日のほとんどのNUMAシステムでさえキャッシュコヒーレントである主な理由でもあります。

キャッシュに一貫性がない場合、「明示的なステップ」は一貫性を強制する必要があります。明示的なステップは通常、クリティカルセクション/ミューテックスのようなものです(たとえば、C / C ++の揮発性はほとんどありません)。ミューテックスなどのサービスが、変更があり、すべてのキャッシュで更新する必要があるメモリのみを追跡することは不可能ではないにしても、非常に困難です。おそらく、すべてのメモリを更新する必要があります。どのコアがキャッシュにそのメモリのどの部分を持っているか。

おそらく、ハードウェアは、変更されたメモリアドレス/範囲を追跡し、それらの同期を維持する上で、はるかに優れた効率的な仕事をすることができます。

そして、コア1で実行され、プリエンプトされるプロセスを想像してみてください。再度スケジュールされると、コア2でスケジュールされます。

キャッシュが選択的でない場合、これはかなり致命的です。そうでない場合、コア2のキャッシュには存在しないコア1のキャッシュにプロセスデータの残りが存在する可能性があります。ただし、そのように動作するシステムの場合、スレッドがスケジュールされるときにOSはキャッシュコヒーレンシを適用する必要があります。これはおそらく「すべてのコア間のキャッシュ内のすべてのメモリを更新する」操作であるか、ダーティページを追跡する可能性があります。 MMUの助けを借りて、変更されたメモリページのみを同期します。この場合も、ハードウェアはキャッシュをよりきめ細かく効率的な方法でコヒーレントに保つ可能性があります。

于 2010-07-14T01:13:40.137 に答える
9

他の著者からの素晴らしい反応ではカバーされていないニュアンスがいくつかあります。

まず、CPUがメモリをバイト単位で処理するのではなく、キャッシュラインを処理することを検討してください。1行は64バイトである可能性があります。ここで、場所Pに2バイトのメモリを割り当て、別のCPUが場所P + 8に8バイトのメモリを割り当て、PとP + 8の両方が同じキャッシュラインに存在する場合、キャッシュコヒーレンスがないことを確認します。 2つのCPUは、お互いの変更を無効にすることなく、PとP+8を同時に更新することはできません。各CPUはキャッシュラインで読み取り-変更-書き込みを行うため、両方が他のCPUの変更を含まないラインのコピーを書き出す可能性があります。最後のライターが勝ち、メモリへの変更の1つが「消えた」でしょう!

覚えておくべきもう1つのことは、一貫性と一貫性の違いです。x86派生CPUでさえストアバッファを使用するため、コンパイラが値を書き戻すことを決定した場合でも、すでに終了した命令が他のCPUがそれらの変更を確認できるようにメモリを変更したと期待できる保証はありません。メモリに(おそらくvolatile?のために)。代わりに、modはストアバッファに配置されている可能性があります。一般的に使用されているほとんどすべてのCPUはキャッシュコヒーレントですが、x86と同じくらい寛容な整合性モデルを備えているCPUはほとんどありません。このトピックの詳細については、たとえば、http://www.cs.nmsu.edu/~pfeiffer/classes/573/notes/consistency.htmlを確認してください。

これがお役に立てば幸いです。ところで、私はCorensicで働いています。この会社は、同時実行デバッガーを構築しているので、チェックアウトすることをお勧めします。並行性、一貫性、および一貫性に関する仮定が根拠のないものであることが判明した場合に、それは断片を拾い上げるのに役立ちます:)

于 2010-07-18T21:12:57.747 に答える
7

あなたがこれを行うと想像してください:

lock(); //some synchronization primitive e.g. a semaphore/mutex
globalint = somevalue;
unlock();

キャッシュコヒーレンスがなかった場合、最後unlock()にそれがどこにでも表示されることを保証するglobalint必要があります。キャッシュコヒーレンスを使用すると、メモリに書き込み、ハードウェアに魔法をかけるだけです。ソフトウェアソリューションは、どのメモリがどのキャッシュに、どのコアに存在するかを把握し、どういうわけかそれらがアトミックに同期していることを確認する必要があります。

同期を維持する必要のあるキャッシュに存在するすべてのメモリを追跡するソフトウェアソリューションを見つけることができれば、賞を獲得できます。これは、現在のハードウェアソリューションよりも効率的です。

于 2010-07-14T01:34:15.380 に答える
1

複数のスレッドを処理していて、複数のスレッドから同じ変数にアクセスしている場合、キャッシュの一貫性は非常に重要になります。その特定のケースではすべてのプロセッサ/コアが同時に変数にアクセスする場合に同じ値を表示するようにする必要があります。そうしないと、驚くほど非決定的な動作になります。

于 2010-07-14T00:38:11.950 に答える
1

ロックには必要ありません。ロックコードには、必要に応じてキャッシュフラッシュが含まれます。主に、同じキャッシュライン内の異なる変数に対する異なるプロセッサによる同時更新が失われないようにする必要があります。

于 2010-07-15T00:30:39.977 に答える
0

キャッシュコヒーレンシはハードウェアに実装されています。これは、プログラマーがマルチコア/マルチプロセッサ環境で動作しているときに、すべてのスレッドがメモリ位置の最新の値を確認することを心配する必要がないためです。キャッシュコヒーレンスは、すべてのコア/プロセッサが独自の個別のキャッシュを持っているにもかかわらず、すべてのコア/プロセッサが単一の統合キャッシュで動作しているという抽象化を提供します。

また、データの一貫性を確保するためにコードを変更することなく、レガシーマルチスレッドコードが新しいプロセッサモデル/マルチプロセッサシステムでそのまま機能することを確認します。

于 2014-11-20T05:48:12.387 に答える