У меня есть 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();
}
}
При вставке элементов с четырьмя потоками, я получил только около 32% использования процессора и плохую производительность. Поэтому я заменил ReaderWriterLockSlim на Monitor (т.е. ключевое слово lock
).
Загрузка ЦП была почти на 100%, а производительность более чем удвоилась.
Мой вопрос: почему увеличилась загрузка процессора? Количество столкновений не должно было измениться. Что заставляет ReaderWriterLock.EnterWriteLock ждать так много раз?