C # Efficient task sharing between cores

I am working on a small simulation that runs on my 8-core workstation. Modeling involves modeling the interaction between a large number of independent nodes. During one phase, I need to perform a series of simple atomic operations for each node in parallel. I am using Parallel.ForEach from System.Threading.Tasks to simultaneously apply the operation to each node in the list of all nodes.

This works well for the 100-500 nodes that I used for testing. The load was balanced very well when all the cores are constantly in use. Unfortunately, when I try to run a simulation with a basic dataset (5000+ nodes), everything goes wrong. All 8 cores in most cases are idle, up to 100% every few seconds, and then return to 1% use. A few minutes after that, an OutOfMemoryException is thrown and the program crashes.

I'm not quite sure what is wrong, but I remain suspicious that my current code generates many threads, which would be optimal for the task. I think that the ideal method for the model would be to determine the number of available kernels N, split the list of nodes into N segments, then generate N threads, providing each thread with a separate section of the list.

I would like to ask if this is really a good solution to the problem, are there better ones and how should this be implemented in C #? Any tips or comments are welcome.

EDIT: sample code on request

Parallel.ForEach(listOfNodes, tempNode => { tempNode.foo(); } ); <snip> void foo() { foreach(myType bar in listOfmyType) { if (bar.isActive) setNodeActive(); } } 
+4
source share
2 answers

See this topic for a discussion of limiting the number of threads used by Parallel.For to prevent memory starvation:

http://connect.microsoft.com/VisualStudio/feedback/details/534571/parallel-foreach-may-create-an-inordinate-number-of-threads

I would try setting ParallelOptions.MaxDegreeOfParallelism around 500 and see what happens.

+3
source

I think that an ideal method would be a model for determining the number of available N kernels, split the list of nodes into N segments, then enter N threads, each thread is a section of the list.

This is exactly what Parallel.ForEach does, so there should be another problem.

It will be very difficult for us to come up with a better flow control system. But you can use your own schedulers in the task library.

+2
source

All Articles