10,000 個の同時タスクの完了を追跡する int の配列があります。値は 1 または 0 です。この配列が Bit の配列であり、各同時スレッドが interlocked.CompareExchange (または同様のもの) を使用すると、より効率的だと思います。 ) 単一のビットを変更します。
Interlocked に「ビット」のオーバーロードがない場合、これにどのようにアプローチすればよいですか?
10,000 個の同時タスクの完了を追跡する int の配列があります。値は 1 または 0 です。この配列が Bit の配列であり、各同時スレッドが interlocked.CompareExchange (または同様のもの) を使用すると、より効率的だと思います。 ) 単一のビットを変更します。
Interlocked に「ビット」のオーバーロードがない場合、これにどのようにアプローチすればよいですか?
ループ内でそれを偽造することはできますがInterlocked.CompareExchange(ref int, int, int)
、より効率的だとは思いません:
private static void SetBit(ref int valueToUpdate, int bitToSet)
{
while (true)
{
int oldValue = valueToUpdate;
int newValue = oldValue | bitToSet;
int result = Interlocked.CompareExchange(ref valueToUpdate, newValue, oldValue);
if (result == oldValue) break;
}
}
を使用してビットでそれを行うことはできないと思いますInterlocked
。ints
各ビットが独自の 内にあるように、 の配列に切り替える必要があると思いますint
。
Interlocked.CompareExchange
int
等しいかどうかのみを比較しますが、ビットへの他の変更を保護するために他の同時実行戦略を使用しない限り、実行できないビットの1つだけを比較する必要がありint
ます。
並行タスクの完了を追跡するには、スレッドセーフな構造が必要です。したがって、インターロックされたコンストラクトは常にロックよりも高速です (ロックを必要としないため) 。 -classの静的メソッドを整数で使用する必要があります (たとえば、0 に相当し、 1 に相当します)。Interlocked
false
true
Jeffrey Richter は、彼の著書「C# による CLR」の第 28 章「プリミティブ スレッド同期コンストラクト」で説明していることと同じことを行います。彼は、彼の Wintellect.PowerThreading ライブラリにも Interlocked コンストラクトに基づく独自のロックの実装を紹介し、優れた説明と、彼自身の実装と .net フレームワークに含まれている実装の時間比較を提供しています。
まず、いいえ、すべてのインターロック機能はメモリ アドレスで動作し、個々のビットはアドレス指定できません。
代わりに何をすべきか?
2 つのオプションを調査します。
InterlockedIncrement
用意し、タスクが完了するたびにそれを行います。すべてのタスクが完了したかどうかを確認するには、値がまだ 10,000 に達しているかどうかを確認します。どれが一番速いかわかりません。パフォーマンスが重要な場合は、ベンチマークしてください。:)