1

I have just did a sample for multithreading using This Link like below:

Console.WriteLine("Number of Threads: {0}", System.Diagnostics.Process.GetCurrentProcess().Threads.Count);            
int count = 0;
Parallel.For(0, 50000, options,(i, state) =>
{
            count++;                
});

Console.WriteLine("Number of Threads: {0}", System.Diagnostics.Process.GetCurrentProcess().Threads.Count);
Console.ReadKey();

It gives me 15 thread before Parellel.For and after it gives me 17 thread only. So only 2 thread is occupy with Parellel.For.

Then I have created a another sample code using This Link like below:

var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 10 };
Console.WriteLine("MaxDegreeOfParallelism : {0}", Environment.ProcessorCount * 10);
Console.WriteLine("Number of Threads: {0}", System.Diagnostics.Process.GetCurrentProcess().Threads.Count);            
int count = 0;
Parallel.For(0, 50000, options,(i, state) =>
{
            count++;                
});

Console.WriteLine("Number of Threads: {0}", System.Diagnostics.Process.GetCurrentProcess().Threads.Count);
Console.ReadKey();

In above code, I have set MaxDegreeOfParallelism where it sets 40 but is still taking same threads for Parallel.For.

So how can I increase running thread for Parallel.For?

Community
  • 1
  • 1
Ravi Solanki
  • 87
  • 1
  • 9
  • 1
    From MSDN: "By default, For and ForEach will utilize however many threads the underlying scheduler provides, so changing MaxDegreeOfParallelism from the default only limits how many concurrent tasks will be used." This is used to limit the number of threads in order to avoid using too many as far as I can tell. – o_weisman Apr 06 '16 at 06:15
  • I am facing a problem that some numbers is skipped inside the *Parallel.For* when I perform some heavy and complex functionality inside it. So here I want to increase the maximum thread and override the skipping issue. I have tried with **lock** but I think it will not gives me parallelism which I want. – Ravi Solanki Apr 06 '16 at 06:28

3 Answers3

2

I am facing a problem that some numbers is skipped inside the Parallel.For when I perform some heavy and complex functionality inside it. So here I want to increase the maximum thread and override the skipping issue.

What you're saying is something like: "My car is shaking when driving too fast. I'm trying to avoid this by driving even faster." That doesn't make any sense. What you need is to fix the car, not change the speed.

How exactly to do that depends on what are you actually doing in the loop. The code you showed is obviously placeholder, but even that's wrong. So I think what you should do first is to learn about thread safety.

Using a lock is one option, and it's the easiest one to get correct. But it's also hard to make it efficient. What you need is to lock only for a short amount of time each iteration.

There are other options how to achieve thread safety, including using Interlocked, overloads of Parallel.For that use thread-local data and approaches other than Parallel.For(), like PLINQ or TPL Dataflow.


After you made sure your code is thread safe, only then it's time to worry about things like the number of threads. And regarding that, I think there are two things to note:

  • For CPU-bound computations, it doesn't make sense to use more threads than the number of cores your CPU has. Using more threads than that will actually usually lead to slower code, since switching between threads has some overhead.
  • I don't think you can measure the number of threads used by Parallel.For() like that. Parallel.For() uses the thread pool and it's quite possible that there already are some threads in the pool before the loop begins.
svick
  • 236,525
  • 50
  • 385
  • 514
  • Appreciate you answers! **Thread-Local Variables** is quite useful to calculate iteration performed by Parallel.For. I have also gone through the TPL which seems helpful to me. I have implemented following code. So do I need to implement any thread safety here as well? `var tasks = new Task[Count]; for (var i = 0; i < Count; i++) { tasks[i] = Task.Factory.StartNew(() => SomeHeavyOpertaion()); } Task.WaitAll(tasks);` – Ravi Solanki Apr 07 '16 at 05:51
  • @RaviSolanki That very much depends on what `SomeHeavyOpertaion()` does. – svick Apr 07 '16 at 12:45
  • I am fetching HTML stream of multiple URL (in my case it's around 47K) and storing in Azure Blob Storage. – Ravi Solanki Apr 07 '16 at 13:31
1

Parallel loops use hardware CPU cores. If your CPU has 2 cores, this is the maximum degree of paralellism that you can get in your machine.

Taken from MSDN:

What to Expect

By default, the degree of parallelism (that is, how many iterations run at the same time in hardware) depends on the number of available cores. In typical scenarios, the more cores you have, the faster your loop executes, until you reach the point of diminishing returns that Amdahl's Law predicts. How much faster depends on the kind of work your loop does.

Further reading:

Community
  • 1
  • 1
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • So that means I don't need to care about **MaxDegreeOfParallelism** as CPU already taken care of number of available cores. Right? – Ravi Solanki Apr 06 '16 at 06:34
  • @RaviSolanki That's it, the more cores your CPU owns, the more tasks in parallel your application can perform at once. – Matías Fidemraizer Apr 06 '16 at 06:35
  • Interesting, As I have already mentioned my query above that I am facing a problem that some numbers is skipped inside the Parallel.For when I perform some heavy and complex functionality inside it. So here I want to increase the maximum thread and override the skipping issue. I have tried with lock but I think it will not gives me parallelism which I want. – Ravi Solanki Apr 06 '16 at 06:39
  • @RaviSolanki In paralell loops, iterations aren't executed in order. It's not iterations are skipped, but they're executed unordered – Matías Fidemraizer Apr 06 '16 at 06:41
  • Yes I understand that it's in executed in random order. I have made the count of the total operation performed inside it where I have set 50000 iteration but after parallel.For I have printed the total count of iteration that has performed and it shows me 37000 something number. Am I missing something? – Ravi Solanki Apr 06 '16 at 06:46
  • @RaviSolanki Well, I don't know what's going on your particular case... I believe I've already answered your question, there should be some issue in your code, I doubt that you've set a `Parallel.For` to do 50k iterations and it only did 37k... – Matías Fidemraizer Apr 06 '16 at 07:34
  • May be so let me go through all the code again. Thanks !! – Ravi Solanki Apr 06 '16 at 08:00
  • @RaviSolanki No problem!! – Matías Fidemraizer Apr 06 '16 at 08:01
0

Parallel loops will give you wrong result for summation operations without locks as result of each iteration depends on a single variable 'Count' and value of 'Count' in parallel loop is not predictable. However, using locks in parallel loops do not achieve actual parallelism. so, u should try something else for testing parallel loop instead of summation.