Вопрос

у меня есть IDictionary<TKey,TValue> реализация, которая внутри содержит другие 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 на монитор (т. е. lock ключевое слово).Загрузка ЦП теперь достигла почти 100%, а производительность выросла более чем вдвое.

Мой вопрос:Почему увеличилась загрузка ЦП?Количество столкновений не должно было измениться.Что заставляет ReaderWriterLock.EnterWriteLock ждать столько раз?

Это было полезно?

Решение

Для загрузки только для записи Monitor дешевле, чем ReaderWriterLockSlim, однако, если вы моделируете нагрузку чтения + записи, где чтение намного превышает запись, тогда ReaderWriterLockSlim должен превзойти Monitor.

Другие советы

Я не гуру, но я предполагаю, что RWLS больше ориентирован на тяжелые конфликты (например, сотни потоков), тогда как Monitor более приспособлен к этим разовым проблемам синхронизации.

Лично я использую TimerLock класс, который использует Monitor.TryEnter с параметром таймаута.

Как узнать, что стало причиной плохой производительности?Вы не можете об этом догадаться, единственный способ — провести какое-то профилирование.

Как вы справляетесь с блокировкой родительской коллекции или она постоянна?

Может быть, вам нужно добавить отладочный вывод и посмотреть, что произойдет на самом деле?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top