ReaderWriterLockSlim vs Monitor

I have an implementation of IDictionary<TKey,TValue> , which internally contains n other Dictionary<TKey, TValue> and distributes these inserts by the HashCode key in the invidual sub-dictionaries. With 16 sub-dictionaries, the number of collisions is rather small on a 4-core machine.

For parallel inserts, I blocked the Add method with ReaderWriterLockSlim , blocking only a separate sub-dictionary:

  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(); } } 

When inserting elements with four threads, I got only about 32% of the processor and poor performance. Therefore, I replaced ReaderWriterLockSlim with a monitor (i.e. the lock keyword). Currently, CPU utilization is almost 100%, and performance has more than doubled.

My question is: why increase CPU usage? The number of collisions should not change. What does ReaderWriterLock.EnterWriteLock do so many times?

+5
multithreading c # locking
source share
3 answers

For recording-only downloads, a monitor is cheaper than ReaderWriterLockSlim, however, if you simulate a read + write load, where reading is much larger than writing, then ReaderWriterLockSlim should turn off the monitor.

+13
source share

I am not a guru, but I assume that RWLS is more focused on heavy rivalry (for example, hundreds of threads), while Monitor more tuned to these one-time synchronization problems.

Personally, I use the TimerLock class, which uses Monitor.TryEnter with a timeout parameter.

0
source share

How do you know the reason for poor performance? You cannot guess, the only way is to do some kind of profiling.

How do you handle the lock for the parent collection or persistent?

Perhaps you need to add debug output and see what actually happens?

0
source share

All Articles