IDictionary<TKey,TValue>
内部でn個のその他Dictionary<TKey, TValue>
を保持し、その挿入をキーのHashCodeによって個々のサブ辞書に配布する実装があります。16 個のサブディクショナリがあるため、4 コア マシンでの衝突の数はかなり少なくなります。
並列挿入の場合、 Add メソッドをReaderWriterLockSlim
でロックし、個々のサブ辞書のみをロックします。
public void Add(TKey key, TValue value)
{
int poolIndex = GetPoolIndex(key);
this.locks[poolIndex].EnterWriteLock();
try
{
this.pools[poolIndex].Add(key, value);
}
finally
{
this.locks[poolIndex].ExitWriteLock();
}
}
4 つのスレッドで項目を挿入すると、約 32% の CPU 使用率しか得られず、パフォーマンスが低下しました。そこで、ReaderWriterLockSlim を Monitor (つまり、lock
キーワード) に置き換えました。CPU 使用率はほぼ 100% になり、パフォーマンスは 2 倍以上になりました。
私の質問は、CPU 使用率が増加したのはなぜですか? 衝突の数は変わっていないはずです。ReaderWriterLock.EnterWriteLock が何度も待たされるのはなぜですか?