あなたの例はうまくいくはずです。
複数のプロセッサは、MESIのようにcoherency protocolを使用して、データがキャッシュ間で同期した状態を維持するようにします。 MESIでは、各キャッシュラインは変更され、排他的に保持され、CPU間で共有されるか、無効であるとみなされます。プロセッサ間で共有されるキャッシュラインを書き込むことは、他のCPUのキャッシュラインを無効にして、キャッシュを同期させた状態にします。
しかし、これでは十分ではありません。異なるプロセッサは異なるmemory modelsを持ち、ほとんどの最新のプロセッサはあるレベルのメモリアクセスの再順序付けをサポートしています。これらの場合、memory barriersが必要です。
例えば
あなたはスレッドAがある場合:
DoWork();
workDone = true;
とスレッドB:両方の別々のプロセッサ上で実行されていると
while (!workDone) {}
DoSomethingWithResults()
が、書き込みは(DoWork内で行わという保証はありません)しますworkDoneおよびDoSomethingWithResults()への書込みが行われる前にスレッドBから見えるようにして、潜在的に一貫性のない状態を続行します。メモリバリアは読み書きの順序を保証します。スレッドAのDoWork()の後にメモリバリアを追加すると、スレッドBが一貫したビューを取得できるように、DoWorkによって行われたすべての読み書きが強制的にwriteDoneに書き込まれます。本質的にミューテックスはメモリバリアを提供するため、読み書きはロックとロック解除の呼び出しを渡すことができません。
あなたのケースでは、1つのプロセッサが他のプロセッサにキャッシュラインをダーティにしたことを通知し、他のプロセッサにメモリからのリロードを強制します。値を読み書きするためにミューテックスを取得することで、メモリへの変更が予想どおりに他のプロセッサに見えることが保証されます。
この応答はありがとうございます。私は言語/コンパイラレベルで何が達成できるのかについて実用的な限界があるように見えるので、ハードウェアレベルのメカニズムのいくつかがここに現れなければならないのか疑問に思っていました。 – csj