29

I'm using a concurrent dictionary to store about two million records and want to know what to initialize the concurrency level of my dictionary to.

The MSDN page has the following comment in its example code:

The higher the concurrencyLevel, the higher the theoretical number of operations that could be performed concurrently on the ConcurrentDictionary. However, global operations like resizing the dictionary take longer as the concurrencyLevel rises.

This is the best I could find that explains what the concurrencyLevel means and yet it is still very vague.

Kit
  • 20,354
  • 4
  • 60
  • 103
Michael Smale
  • 583
  • 9
  • 15

2 Answers2

25

The most important thing to understand is that even if you have more concurrent accesses than the concurrencyLevel, operations will still be thread-safe. That is, setting concurrencyLevel is a matter of performance, not correctness.

concurrencyLevel specifies the number of independent locks which are available for map operations. Each lock is associated with a different subset of the hash space, so accessing a given element requires holding a particular lock. This means that one thread's access may block another thread's, even if the number of concurrent accesses is well below concurrencyLevel. Raising the number of locks reduces the probability of lock contentions, but increases the cost of operations which must acquire all locks (those which examine the collection as a whole, such as Count, IsEmpty, or Values, as well as Add() when it needs to resize the table).

Profiling your application is really the only way to determine the optimal concurrencyLevel. Setting it to the expected number of worker threads is a good start, though.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • Agree on the profiling part. It really is the only way to tell. – Jason Hernandez Aug 26 '15 at 06:06
  • Can you explain what tools you might use to profile this (i.e. VS Concurrency Visualizer). Also, specifically what am I looking for in the during profiling that indicates to me I should increase / change the concurrencyLevel? – Jake Drew Oct 01 '15 at 15:08
  • 1
    Old post but JetBrains DotTrace is a good product to start with for profiling. – rollsch Apr 21 '21 at 00:18
1

If you just want to set the initial capacity and don't know what concurrencyLevel you should use, just resort to Environment.ProcessorCount, since the collections default concurrency level value is PlatformHelper.ProcessorCount.

ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89