I am aware of tasks that offer fine grained control for short running tasks but I have a situation where it is more natural to use a foreach loop. The question is, is it possible to tell Parallel.For to expect short-running operations and use as many threads as possible to max out the CPU?
If not, then what method would you suggest to parallelize:
bool [,] grid = new bool [1000, 1000];
for (int y=0; y<1000; y++)
for (int x=0; x<1000; x++)
// Ignore the bounds error. This is just to illustrate a very short operation.
grid[x, y] |= grid[x-1, y+1];
Yes, you can do this by making a
Partitioner<T>and handling the partitioning yourself. For details, see How to: Speed Up Small Loop Bodies.However, in your case, it might be better to just parallelize the outer loop, and leave the inner loop sequential inside of each of the outer
Parallel.Forloop bodies. This would give each work item enough instructions that it would probably use the processor adequately.That being said, this is a situation where .NET will likely not do a great job with
Parallel.For– at least not without some extra work. By assiging values to the same array in parallel, you’re going to be introducing false sharing due to the implicit array bounds check, which reads from the same location (just before the start of the array).There are various approaches to working around this – one option might be to switch from a multidimensional to a jagged array, for example. With the proper indexing and looping, this can reduce the number of writes to “shared” arrays. Another option would be to use unsafe code and pointers instead of direct array access, as this avoids the bounds checks, but requires very careful coding.