以下は、に基づくインターロックされたメソッドの実装ですInterlocked.CompareExchange
。
このコードでSpinWait
繰り返しを行う前にスピンを使用することをお勧めしますか?
public static bool AddIfLessThan(ref int location, int value, int comparison)
{
int currentValue;
do
{
currentValue = location; // Read the current value
if (currentValue >= comparison) return false; // If "less than comparison" is NOT satisfied, return false
}
// Set to currentValue+value, iff still on currentValue; reiterate if not assigned
while (Interlocked.CompareExchange(ref location, currentValue + value, currentValue) != currentValue);
return true; // Assigned, so return true
}
私はSpinWait
このシナリオで使用されているのを見てきましたが、私の理論では、それは不必要なはずです。結局のところ、ループには少数の命令しか含まれておらず、常に1つのスレッドが進行しています。
このメソッドを実行するために2つのスレッドが競合していて、最初のスレッドはすぐに成功するが、2番目のスレッドは最初は何も変更を行わず、繰り返す必要があるとします。他の候補がない場合、2番目のスレッドが2回目の試行で失敗することはまったく可能ですか?
例の2番目のスレッドが2回目の試行で失敗しない場合、SpinWait
?で何が得られるでしょうか。メソッドを実行するために100のスレッドが競合しているというまれなイベントで、数サイクルを削ぎ落としますか?
SpinOnce
シングルスレッドのOSが枯渇するのを防ぐためだけに使用する必要があるでしょう。stackoverflow.com/questions/37799381/…を
Interlocked
ます。明確にするために、私はCPUサイクルSpinWait
を意味のある形で節約したり、(@ MatthewWatsonに感謝)シングルスレッドOSが不足したりしないようにするなど、が意味があるかどうかにのみ関心があります。
SpinWait
とにかく同じ数の試行が実行されるので、それは私がそれが電力消費を減らすことさえないと期待する理由です!(2つのスレッドがある場合、これは最初のスレッドで1回、2番目のスレッドで2回の試行です。)