最近、メモリの再注文が行われています。私の質問は、マルチスレッドシナリオに関するものです。以下の例を考えてみましょう:メモリの順序付け、他の実行とマルチスレッドの安全性なし
A = 0;
B = 0;
Thread 1 on Processor 1 Thread 2 on Processor 2
A = 100; while(B== 0);
B = 1; //access A here
私はX86-64 Windowsプラットフォーム上でコーディングし、AとBに格納する(コンパイラレベルまたはハードウェアレベルでのいずれか)並べ替えることができ、私が終わる可能性があると考えたことがないされていますスレッド2ではB = 0であり、Aはまだ0であることがわかります。このようなコードでは、問題や厄介なバグは発生しませんでした。それはx86-x64が強く注文されており、WindowsのCコンパイラも同様です。
弱い順序のメモリを持つ他のプラットフォームでこのようなコードを実行するには、ロック内でAとBを更新してアクセスする必要があります(基本的なロックの実装でメモリバリアが使用され、以前のすべてのロードおよびストアがすべてのプロセッサコアで表示された後にのみリリースされます)。
おかげ
LMimseyを最大限に活用すると、コンパイラレベルの並べ替えが可能になります。私は "これはCメモリモデルでは許可されていません"ということはありませんでした。強く順序付けられたx86は、上記の例が得ようとしているB = 1のときにA = 100を保証するはずです。 – san216
また、私の質問の次の部分は、弱い順序のメモリを持つプラットフォームでは、ロック内でAとBの両方を更新するように気を付ける必要があります。すべてのOSプラットフォーム上のロックプリミティブは、ロック解除ロジックの内部にメモリバリアを挿入します。そうしないと、ロックがハードウェアメモリアクセスの順序変更を防ぐことができないためです。 – san216
2つ以上のスレッドによる単一のメモリ位置への読み取り/書き込みアクセスは、メモリモデルルール(別名データ競合)に違反しています。結果は未定義の動作です。例えば、あなたのコンパイラは 'B'がコア2で更新されることを期待していないかもしれないので、単純にループから取り除くかもしれません。ループは決して終了しません。 – LWimsey