Posted by: Cirilo Meggiolaro | 05/13/2009

Tip of the day #211 – .NET Framework 4.0 – Your first parallel loop

Let’s check today how to write a simple For loop using parallel programming. Basically the parallel programming takes advantage of the multi-processor computing and the .NET Framework 4.0 provides a set of tools to help you out developing multi-thread applications.

Method Overloads

The most basic Parallel For loop overload accepts a start index (inclusive), an end index (exclusive) and a delegate that is executed once per iteration.

  • ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int, ParallelLoopState> body);
  • ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);
  • ParallelLoopResult For(long fromInclusive, long toExclusive, Action<long, ParallelLoopState> body);
  • ParallelLoopResult For(long fromInclusive, long toExclusive, Action<long> body);
  • ParallelLoopResult For(int fromInclusive, int toExclusive, ParallelOptions parallelOptions, Action<int, ParallelLoopState> body);
  • ParallelLoopResult For(int fromInclusive, int toExclusive, ParallelOptions parallelOptions, Action<int> body);
  • ParallelLoopResult For(long fromInclusive, long toExclusive, ParallelOptions parallelOptions, Action<long, ParallelLoopState> body);
  • ParallelLoopResult For(long fromInclusive, long toExclusive, ParallelOptions parallelOptions, Action<long> body);

Generic overloads

The generic overloads give you all the flexibility to perform Parallel For loops against several different types and control each the state for each thread execution:

  • ParallelLoopResult For<TLocal>(int fromInclusive, int toExclusive, Func<TLocal> localInit, Func<int, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally);
  • ParallelLoopResult For<TLocal>(long fromInclusive, long toExclusive, Func<TLocal> localInit, Func<long, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally);
  • ParallelLoopResult For<TLocal>(int fromInclusive, int toExclusive, ParallelOptions parallelOptions, Func<TLocal> localInit, Func<int, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally);
  • ParallelLoopResult For<TLocal>(long fromInclusive, long toExclusive, ParallelOptions parallelOptions, Func<TLocal> localInit, Func<long, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally);

How to

Let’s create a simple Parallel For loop that performs a sum of all numbers existing from zero until the number passed as parameter:

public void ParallelCalculation(int maximum)
{
    int subTotal = 0;

    Parallel.For(0, sequenceSize, i =>
    {
        subTotal += i;
    });
}

On the previous method we are passing three parameters to the Parallel For loop: the start and end indexes and a delegate that is executed once per iteration.

The following method is the same code implementation but with sequential programming.

public void SequentialCalculation(int maximum)
{
    int subTotal = 0;

    for (int i = 0; i < maximum; i++)
    {
        subTotal += i;
    }
}

Performance

Let’s use both methods shown previously to make a really simple performance test by executing several times with different parameters. The time to perform the calculation changes from computer to computer when you have different numbers of processors. Running the application on a laptop with 2 processors the results were (in milliseconds):

Parameter        Sequential        Parallel

1,000                      17ms          16ms

1,000,000                69ms          59ms

5,000,000              410ms         365ms

50,000,000          3142ms        2796ms

Let’s add a Console.WriteLine that writes the partial results of the calculation to the Console window to check how the execution time changes:

Parameter        Sequential        Parallel

1,000                    643ms          519ms

10,000               2,821ms        1,727ms

100,000            21,164ms      13,799ms

1,000,000        239,585ms    129,016ms

Let’s check tomorrow how to work with Parallel For Each loops.

Stay tuned!

Advertisements

Responses

  1. Microsoft is dramatically changing the way we code. As always, nice job Cirilo.

  2. Interesting feature.

    I suppose there got to be multiple threads processing this (since they are on different processors) am I right?

    If so, what is the idea on how could we achieve better performance as we need to lock the variable at the time of updating it.

    Any clarification of how this Parallel will impact threading issues will be very helpful.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: