Can .NET Dictionary performance degrade with multithreaded access?
I have a situation where, in a multithreaded application, many different threads are accessing a Dictionary at the same time. It appears that this could be a bottleneck, but it's unclear - a plausible scenario is that multiple threads may be trying to retrieve the same value (do note, however, that the data structure is fixed - no thread is doing any writing, but dozens could be trying to read the same value). The question is, can multiple threads read the same v开发者_StackOverflowalue simultaneously, or is it one at a time? If so, is there any other data structure that could be used?
Multiple threads should have no problem reading the same memory value. There may be a small wait at the OS or hardware level while the memory is actually accessed for each thread, but that's miniscule in most cases, and not easy to work around.
What got my attention about your description of the problem is that "dozens [of threads] could be trying to read the same value". If you have dozens of active threads processing at once, the bottleneck is thread management. Like anything, there is a law of diminishing returns, and diseconomies of scale; with current hardware, at about twice the number of active threads as "execution units" (cores, HT logical processors, however the architecture handles multithreaded execution), your CPU starts spending more time scheduling thread execution and managing thread states than it is actually executing the threaded instructions. Yes, your Task Manager may show hundreds of threads in flight, but the overwhelming majority of these are "sleeping", listening for user interaction, or just waiting (like polling threads).
I would look at reducing the number of threads to no more than two per "execution unit", and ideally only a couple more than the number of execution units (so EUs have a thread to "switch to" while the FSB is reading memory for another thread). That will reduce the overhead time your computer spends managing all these threads.
If you aren't doing any lock()
-ing anywhere around access to the Dictionary
in question, I doubt that could be the source of your trouble. If you are only reading values and never writing, there should be no need for locking (though you should also take into account access to the member variables of the Dictionary items, too).
Locking could cause some degradation alone if you had a LOT of threads frequently locking, but if that were the case I think you'd hit performance issues along other lines. Also, of course, if locking is not implemented correctly, you could have deadlocks or unnecessary locking.
If you don't need to provide locks, then perf will be on par or better when multiple threads read from the collection. One could inspect dictionary implementation in reflector and see if there are any places that modify state of backing hashtable. I don't believe it will be a problem.
It can, yes. That doesn't necessarily mean that it is going to though.
If you're locking the Dictionary for Read/Write access, there's going to be overhead for locking...not to mention the possibility of Deadlocks.
Without locking, performance shouldn't be degraded.
精彩评论