ReaderWriterLockSlim vs.-Monitor
-
03-07-2019 - |
Frage
ich eine IDictionary<TKey,TValue>
Implementierung haben, die intern n andere Dictionary<TKey, TValue>
und verteilt, dass Einblendungen durch HashCode der Schlüssel zu den invidual Unter Wörterbücher hält. Mit 16 Unter Wörterbücher, ist die Anzahl der Kollisionen ziemlich niedrig auf einer 4-Core-Maschine.
Für die parallelen Einfügungen, i verschloss die Add-Methode mit einem ReaderWriterLockSlim
, nur dem einzelnen Teil Wörterbuch Verriegelung:
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();
}
}
Wenn Elemente mit vier Threads eingefügt, ich habe nur etwa 32% CPU-Auslastung und schlechte Leistung. So ersetzte ich das ReaderWriterLockSlim durch einen Monitor (das heißt, die lock
Schlüsselwort).
CPU-Auslastung war jetzt bei fast 100% und die Leistung war mehr als verdoppelt.
Meine Frage ist: Warum hat die CPU-Auslastung erhöhen? Die Anzahl der Kollisionen sollte nicht geändert haben. Was macht ReaderWriterLock.EnterWriteLock so oft warten?
Lösung
Für Schreib nur der Monitor laden ist billiger als ReaderWriterLockSlim jedoch, wenn Sie + schreibt Last lesen simulieren, wo Lese ist viel größer als schreiben, dann sollte ReaderWriterLockSlim durchführen out-Monitor.
Andere Tipps
Ich bin kein Guru, aber meine Vermutung ist, dass RWLs eher auf schweren Anstoß ist (zum Beispiel Hunderte von Threads), während Monitor
mehr abgestimmt auf diesen einmaligen Synchronisierungsproblemen ist.
Ich persönlich verwende eine TimerLock
Klasse, die die Monitor.TryEnter
mit einem Timeout-Parameter verwendet.
Wie wissen Sie, was die schlechte Leistung verursacht? Sie können nicht gehen zu erraten es, die einzige Möglichkeit, eine Art von Profilierung zu tun ist.
Wie gehen Sie für die übergeordnete Sammlung Sperren oder ist es konstant?
Vielleicht müssen Sie einige Debug-Ausgabe addieren und sehen, was wirklich passiert?