タイトなループで単一の配列を更新する複数のスレッドがあります。(デュアルコア プロセッサで 10 スレッド @ 毎秒約 100000 更新)。配列がミューテックス (WaitForSingleObject / ReleaseMutex) の保護下で更新されるたびに。私は、スレッドが配列に対して 2 つの連続した更新を行うことはないことに気付きました。つまり、同期に関連する何らかの収量が必要です。これは、毎秒約 100000 のコンテキスト スイッチが発生していることを意味し、最適とは言えません。なぜこれが起こるのですか?
2 に答える
ここでの問題は、すべての待機スレッドの順序があることです。
WaitForSingleObject でブロックされた各スレッドは、キューに入り、スケジューラによって一時停止されるため、実行時間がこれ以上消費されません。ミューテックスが解放されると、待機中のスレッドの 1 つがスケジューラによって再開されます。スレッドがキューからウェイクアップされる正確な順序は特定されていませんが、多くの場合、単純な先入れ先出しになります。
同じスレッドがミューテックスを解放し、同じミューテックスで別の WaitForSingleObject を実行すると、キューに再挿入され、キューの先頭に挿入される可能性はほとんどありません。すでに他のスレッドが待機しています。彼がキューの先頭にスキップできるようにすると、他のスレッドが枯渇する可能性があるため、これは理にかなっています。したがって、スケジューラはおそらく彼を一時停止し、代わりにキューの先頭にあるスレッドを起動します。
これはマルチプロセッサのおかげだと思います。
最初のスレッド (最初のプロセッサで実行中) がミューテックスを解放すると、2 番目のスレッド (2 番目のプロセッサで実行中) がそれを取得します。最初のスレッドがミューテックスを取得しようとしても取得できません。ミューテックスが 2 番目のスレッドによって最終的に解放されると、(最初のプロセッサ上の) 3 番目のスレッドによって取得されます。