質問

Visual C++ のドキュメントで、複数のスレッドが同じオブジェクトから読み取るのは安全であると読みました。

私の質問は次のとおりです。複数のコアを備えた X86-64 CPU はこれをどのように処理しますか?

1 MB のメモリ ブロックがあるとします。異なるスレッドは文字通りまったく同じデータを同時に読み取ることができますか、それともコアは一度に 1 つのワードのみを読み取り、一度に特定のワードを読み取ることができるのでしょうか?

役に立ちましたか?

解決

異なるコアがメモリの同じブロックから読み取ることができるだけでなく、同時に書き込むこともできます。それが「安全」かどうかは全く別の話です。特に許可されていない方法で複数のコアがメモリの同じブロックをめぐって競合しないようにするには、コードに何らかのガード (通常はセマフォまたはセマフォの派生を使用して行われます) を実装する必要があります。

コアが一度に読み取るメモリのサイズは通常レジスタ 1 個分に相当し、32 ビット CPU では 32 ビット、64 ビット CPU では 64 ビットなどとなります。ストリーミングさえも dword ごとに行われます (たとえば memcpy を見てください)。

複数のコアが実際にどのように同時実行されるかについては、すべてのコアが単一のバスを使用してメモリの読み取りと書き込みを行うため、リソース (RAM、外部デバイス、浮動小数点処理ユニット) へのアクセスは、一度に 1 つのリクエスト、一度に 1 つのコアとなります。 。ただし、コア内部の実際の処理は完全に同時実行されます。DMA 転送もバスをブロックせず、同時転送はキューに入れられ、一度に 1 つずつ処理されます (これについては 100% 確信はありませんが、私はそう信じています)。

編集:明確にするために、ここでの他の返信とは異なり、私はキャッシュなしのシナリオについてのみ話しています。もちろん、メモリがキャッシュされた場合、読み取り専用アクセスは完全に同時実行されます。

他のヒント

1MB ブロックに実際に書き込みがない場合は、書き込みがコミットされていないため、各コアは問題なく独自のキャッシュ ラインから読み取ることができ、したがってキャッシュ コヒーレンシの問題は発生しません。

マルチコア アーキテクチャでは、基本的にコアごとにキャッシュがあり、最新の情報を持たない一部のコアのキャッシュを無効にする「キャッシュ コヒーレンス プロトコル」が存在します。ほとんどのプロセッサが実装していると思います MOESIプロトコル キャッシュの一貫性のため。

キャッシュ コヒーレンシは、主に議論されている複雑なトピックです (私は Joe Duffy によるいくつかの記事が特に好きです) ここ そして ここ)。それにもかかわらず、議論はコードのパフォーマンス上のペナルティの可能性を中心に展開しています。このペナルティは、見かけ上ロックフリーであるにもかかわらず、プロセッサのキャッシュ全体でコヒーレンシを維持するためにキャッシュコヒーレンシプロトコルが作動するために速度が低下する可能性がありますが、書き込みがない限り、単に書き込みが行われないだけです。一貫性が維持されるため、パフォーマンスが失われることはありません。

明確にするために、コメントで述べたように、x86 および x64 アーキテクチャはコア間で共有される単一のバスを実装しているため、RAM には同時にアクセスできません。 SMP メインメモリへのアクセスの公平性を保証します。それにもかかわらず、この状況は各コア キャッシュによって隠蔽され、各コアがデータの独自のコピーを保持できるようになります。1MB のデータの場合、コアがキャッシュを更新するときに競合が発生する可能性がありますが、それは無視できる程度です。

いくつかの役立つリンク:

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top