最近のCPUアーキテクチャでは、パフォーマンスの最適化が採用されているため、実行が順不同になる可能性があります。シングルスレッドアプリケーションでは、メモリの並べ替えも発生する可能性がありますが、プログラムの順序でメモリにアクセスしたかのように、プログラマーには見えません。また、SMPの場合、ある種のメモリ順序を強制するために使用されるメモリバリアが救いの手を差し伸べます。
よくわからないのは、ユニプロセッサでのマルチスレッドについてです。次の例を考えてみましょう。スレッド1が実行されると、tof
のストアがtoのストアの前に発生する可能性がありx
ます。f
が書き込まれた後、および書き込まれる直前にコンテキストスイッチが発生するとしますx
。これでスレッド2が実行を開始し、ループを終了して0を出力します。これはもちろん望ましくありません。
// Both x, f are initialized w/ 0.
// Thread 1
x = 42;
f = 1;
// Thread 2
while (f == 0)
;
print x;
上記のシナリオは可能ですか?または、スレッドコンテキストの切り替え中に物理メモリがコミットされるという保証はありますか?
このウィキによると、
プログラムがシングルCPUマシンで実行される場合、ハードウェアは必要な簿記を実行して、すべてのメモリ操作がプログラマーによって指定された順序(プログラム順序)で実行されたかのようにプログラムが実行されるようにします。したがって、メモリバリアは必要ありません。
ユニプロセッサマルチスレッドアプリケーションについては明示的に言及されていませんが、このケースが含まれています。
それが正しい/完全かどうかはわかりません。これはハードウェア(弱い/強いメモリモデル)に大きく依存する可能性があることに注意してください。したがって、回答に知っているハードウェアを含めることをお勧めします。ありがとう。
PS。ここでは、デバイスのI/Oなどは私の関心事ではありません。そして、それはシングルコアユニプロセッサです。
編集:リマインダーをくれたNitsanに感謝します。ここではコンパイラの並べ替えはなく(ハードウェアの並べ替えのみ)、スレッド2のループは最適化されていないと想定しています。繰り返しになりますが、悪魔は詳細にあります。