Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Parallel.For?

I have recently moved to C#.net 4.

I love Parallel.For, but not sure when to use and when not to. I know that when order is not important for me - I'll use it.

But are there any tests regarding the overhead of working with Parallels? Meaning, if my loop runs only 10 times (and performs very little logic) - should I avoid Parallels? Are there any thumb rules?

like image 355
Faruz Avatar asked Sep 15 '10 08:09

Faruz


People also ask

Is it possible to use parallel for each loop?

The short answer is no, you should not just use Parallel.ForEach or related constructs on each loop that you can. Parallel has some overhead, which is not justified in loops with few, fast iterations.

What is the use of parallel for in C++?

Sometimes, the method calls can be called in a parallel way—in any order. A speedup. When we can use parallel calls, we can speed up some programs by 4 times on a quad-core processor. We can use Parallel.For to make this optimization easier. Parallel example. Using Parallel.For makes programs easier to parallelize.

Why should I avoid using parallel programming?

I would avoid using Parallel.For unless performance is an issue. Writing code that runs concurrently is in general harder than writing single threaded code. Furthermore if you make an error due to a concurrency issue it can be difficult to debug it. For example the bug might occur only sometimes and not be easily reproducible.

How do you write a method in parallel?

We can place each element in an input array, and then have a method write an output in another array. And We can call Parallel.For to call the method in parallel, giving us speedups of several times. Tip If each input and output position is separate, no conflicts will arise during execution, making parallel processing safe.


2 Answers

I would avoid using Parallel.For unless performance is an issue.

Writing code that runs concurrently is in general harder than writing single threaded code. Furthermore if you make an error due to a concurrency issue it can be difficult to debug it. For example the bug might occur only sometimes and not be easily reproducible. Unless you have a specific need for increased performance I would suggest that you keep it simple and use an ordinary loop on a single thread.

like image 80
Mark Byers Avatar answered Oct 26 '22 23:10

Mark Byers


The Parallel.For loop uses ThreadPool to execute work in a loop by invoking a delegate once per each iteration of a loop.

The general idea of how Parallel.For works can be presented as follows:

public static void MyParallelFor(int inclusiveLowerBound, int exclusiveUpperBound, Action<int> body)
{
    // Get the number of processors, initialize the number of remaining
    // threads, and set the starting point for the iteration.
    int numProcs = Environment.ProcessorCount;
    int remainingWorkItems = numProcs;
    int nextIteration = inclusiveLowerBound;
    using (ManualResetEvent mre = new ManualResetEvent(false))
    {
        // Create each of the work items.
        for (int p = 0; p < numProcs; p++)
        {
            ThreadPool.QueueUserWorkItem(delegate
            {
                int index;
                while ((index = Interlocked.Increment(ref nextIteration) - 1) < exclusiveUpperBound)
                    body(index);

                if (Interlocked.Decrement(ref remainingWorkItems) == 0)
                    mre.Set();
            });
        }
        // Wait for all threads to complete.
        mre.WaitOne();
    }
}

Parallel.For returns ParallelLoopResult value type, which contains details on the completed loop. One of its overloads is as follows:

public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);

It's important to realize that parallel execution is not always faster than serial execution. To decide whether to use parallel or not you have to estimate the workload that will do per iteration of a loop. If the actual work being performed by the loop is small relatively to thread synchronization cost, it's better to use ordinary loop.

This is one of example when serial for loop performance is faster that parallel:

static void Main(string[] args)
{
    Action<int> action = new Action<int>(SimpleMethod);

    // ordinary For loop performance estimation
    var sw = Stopwatch.StartNew();

    for(int i = 0; i < 1000; i++)
        action(i);

    Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds);

    // parallel For loop performance estimation
    sw = Stopwatch.StartNew();

    Parallel.For(0, 1000, action);

    Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds);
}

static void SimpleMethod(int index)
{
    int d = 1;
    int result = index / d;
}

Output:

0.0001963 sec.
0.0346729 sec.
like image 26
Dmitry Stepanov Avatar answered Oct 26 '22 22:10

Dmitry Stepanov