9

以下は、 に基づく連動メソッドの実装です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 のスレッドが競合しているという万一の場合に、数サイクルを削減しますか?

4

2 に答える 2

2

専門家ではない私の意見では、2 つのスレッドが をときどき呼び出すこの特定のケースではAddIfLessThan、 aSpinWaitは不要です。2 つのスレッドが両方ともタイトなループで呼び出している場合に、AddIfLessThan各スレッドが数マイクロ秒中断されることなく進行できるようにすることが有益である可能性があります。

実際に私は実験を行いAddIfLessThan、タイトなループで 1 つのスレッドを呼び出す場合と 2 つのスレッドを呼び出す場合のパフォーマンスを測定しました。2 つのスレッドが同じ数のループを (累積的に) 行うには、ほぼ 4 倍の処理が必要です。ミックスにa を追加するSpinWaitと、2 つのスレッドは単一のスレッドよりもわずかに遅くなります。

于 2019-11-04T17:27:00.347 に答える