Visual C ++のドキュメントで、複数のスレッドが同じオブジェクトから安全に読み取れることを読みました。
私の質問は、複数のコアを備えたX86-64CPUはこれをどのように処理するのかということです。
1MBのメモリブロックがあるとします。異なるスレッドは文字通りまったく同じデータを同時に読み取ることができますか、それともコアは一度に1つの単語を読み取ることができ、コアは一度に1つの単語のみを読み取ることができますか?
Visual C ++のドキュメントで、複数のスレッドが同じオブジェクトから安全に読み取れることを読みました。
私の質問は、複数のコアを備えたX86-64CPUはこれをどのように処理するのかということです。
1MBのメモリブロックがあるとします。異なるスレッドは文字通りまったく同じデータを同時に読み取ることができますか、それともコアは一度に1つの単語を読み取ることができ、コアは一度に1つの単語のみを読み取ることができますか?
1MBブロックに実際に書き込みがない場合は、書き込みがコミットされていないため、キャッシュコヒーレンシの問題が発生しないため、各コアは問題なく独自のキャッシュラインから読み取ることができます。
マルチコアアーキテクチャでは、基本的に各コアにキャッシュがあり、最新の情報を持たない一部のコアのキャッシュを無効にする「キャッシュコヒーレンスプロトコル」があります。ほとんどのプロセッサは、キャッシュコヒーレンシのためにMOESIプロトコルを実装していると思います。
キャッシュコヒーレンシは、主に議論されてきた複雑なトピックです(私は、こことここでJoe Duffyによるいくつかの記事が特に好きです)。それにもかかわらず、議論は、明らかにロックフリーであるが、プロセッサキャッシュ全体のコヒーレンシを維持するためにキャッシュコヒーレンシプロトコルが開始されるために速度が低下する可能性があるコードのパフォーマンスペナルティの可能性を中心に展開しますが、書き込みがない限り、単に維持するための一貫性、したがってパフォーマンスの損失はありません。
明確にするために、コメントで述べたように、x86およびx64アーキテクチャは、メインメモリへのアクセスの公平性を保証するSMPを備えたコア間で共有される単一のバスを実装するため、RAMに同時にアクセスすることはできません。それにもかかわらず、この状況は、各コアがデータの独自のコピーを持つことを可能にする各コアキャッシュによって隠されています。1MBのデータの場合、コアがキャッシュを更新しているときに競合が発生する可能性がありますが、それはごくわずかです。
いくつかの便利なリンク:
異なるコアが同じメモリブロックから読み取ることができるだけでなく、同時に書き込むこともできます。それが「安全」であるかどうかにかかわらず、それはまったく別の話です。特に許可されていない方法で同じメモリブロックをめぐって複数のコアが競合するのを防ぐために、コードに何らかのガードを実装する必要があります(通常はセマフォまたはそれらの派生物で行われます)。
コアが一度に読み取るメモリのサイズについては、通常、レジスタの価値があり、32ビットCPUでは32ビット、64ビットCPUでは64ビットなどです。ストリーミングでさえ、dwordごとに行われます(たとえば、memcpyを見てください)。
マルチコアの同時実行の実際については、すべてのコアが単一のバスを使用してメモリの読み取りと書き込みを行うため、リソース(RAM、外部デバイス、浮動小数点処理ユニット)へのアクセスは、一度に1つの要求、一度に1つのコアになります。 。ただし、コア内の実際の処理は完全に並行しています。DMA転送もバスをブロックせず、同時転送は一度に1つずつキューに入れられて処理されます(これについては100%確実ではないと思います)。
編集:明確にするために、ここでの他の返信とは異なり、私はキャッシュなしのシナリオについてのみ話している。もちろん、メモリがキャッシュされた場合、読み取り専用アクセスは完全に同時実行されます。