A brief overiew of the new Parallel Extensions in .NET Framework 4

This post is followup of my previous post that described some of the exciting new features of .NET Framework 4. We have been creating multi-threaded applications with the previous versions of .NET framework, but most of the times, the objective of such multi-threading was to keep the user interface active in case of any IO or network operation going on. However, to cope with the current era of multi-core processors, we need to additionally parallelize our business logic operations to best utilize the computational powers. This post will walk through some of the inconveniences with the traditional multi-threading techniques and will then discuss how the new parallel extensions in .NET Framework 4 help us to introduce parallelism in a better, manageable, scalable and efficient way.

Multi-threading with previous versions of .NET
Microsoft .NET framework, has support for multi-threaded programming since its first version. It allows concurrent execution of several threads sharing the same address space and hence same objects. A multi-threaded application can utilize the powers of multiple cores since each thread can run on a separate core. The .NET framework contains classes that leverage multi-threading under System.Threading namespace. This namespace contains special classes and constructs for creation of threads, their synchronization, scheduling, wait handles, semaphores, mutex, etc. The following code is an example of creation of a new thread in C#:

public static void Main()
{
  //prepare the new thread
  ThreadStartDelegate delegate = new ThreadStartDelegate( MyFunction );
  Thread thread = new Thread( delegate );

  //start the new thread
  thread.Start();

  //wait for the thread to finish
  thread.Join();
}
public void MyFunction()
{
  Console.WriteLine( "This function is running in a separate thread" );
}

Such approach is used when we want to manually create threads, and want to take care of their scheduling and synchronization. However, .NET Framework provides a ThreadPool static class that automatically maintains a pool of worker threads and schedules them. With the thread pool, we just need to insert our methods to a queue, the queue is then monitored by the framework and our methods are executed whenever a worker thread is available. By default, the thread pool has a limit of 250 maximum worker threads per CPU core but this limit can be changed as well. Here’s a code snippet that demonstrates the use of thread pool:

//global flag, to know when our work item is completed
ManualResetWaitHandle waitHandle = new ManualResetWaitHandle(false);

public static void Main()
{
  //insert the method to the system-maintained queue
  //we don’t need to start the thread explicitly
  ThreadPool.QueueUserWorkItem( new WaitCallBack(MyFunction) );

  //wait for the work item to finish
  waitHandle.WaitOne();
}

public void MyFunction(Object state)
{
  Console.WriteLine( "This function is running in a separate thread" );

  //signal the completion of this thread
  waitHandle.Signal();
}

Inconveniences in traditional Multi-Threaded Programming
The traditional multi-threaded programming using System.Threading namespace in .NET framework is not easy, especially when applications grow more complex. We may quickly jump into race conditions, deadlocks and other synchronization problems. Getting to the root cause of such problems is even more difficult since parallel applications cannot be debugged using traditional debuggers due to multiple call stacks. Although, using the ThreadPool class simplifies the management of threads but it is designed for fire-and-forget scenarios and so has certain limitations. For example, we cannot cancel a work item after it has been entered into the queue. Also, there are no notifications when a particular work item is completed, so we need to handle the synchronization using WaitHandles and Reset Events as demonstrated in the example above. Thus, there exists a need for a simplified platform.

The New Parallel Extensions in .NET Framework 4
The parallel extensions in .NET framework 4 enable us to write fine-grained, efficient and scalable parallel code in a natural manner without having them to deal directly with threads, or the thread pool. Using these extensions, we can conveniently write parallel versions of existing sequential code that can automatically utilize all available processors, thus providing a significant speed-up. These new Task Parallel Library nicely addresses the limitations we discussed about thread pools previously. In .NET 4, the unit of work is called task and it gives much more control as compared to the work items in thread pool. Visual Studio 2010 contains new diagnostic tools specially designed to debug parallel applications; some of the new debugging features include Parallel Tasks, Parallel Stacks, Cores View, CPU Utilization View and Thread View.

Data Parallelism in .NET Framework 4
The execution of multiple data streams in parallel can be performed in the new .NET framework using special for loops. We have got parallel implementations for the two mostly used loops: Parallel.For and Parallel.ForEach under System.Threading.Tasks.Parallel class. The main advantage of these for loops is that the syntax and semantics are much similar to the traditional sequential loops. Let’s look at the syntax of the For loops:

//sequential
for (int i=0; i<count; i++)
{
  //for loop body
}
//control passes here when the entire loop is finished

//parallel
Parallel.For (0, count, delegate int(i)
{
  //for loop body
});
//control passes here when the entire loop (all parallel iterations) is finished

Notice that the control is passed to the statement following the loop only after the entire loop is finished. This is great since it would have required some explicit synchronization in the traditional thread pooling technique. Another advantage comes when we need to break from our loop. Again, this would be difficult to achieve using thread pool but the new constructs ParallelLoopState.Break() and ParallelLoopState.Stop() simplify such operators a lot. Similar discussion remains true for Parallel.ForEach loop. Introducing Parallelism in our LINQ queries using PLINQ is even more simpler, as all we need to do is to use the AsParallel() extension method to our collections.

//sequential
var evenNums = 
  from num in numbers
  where num % 2 == 0
  select num;


//parallel
var evenNums = 
  from num in numbers.AsParallel()
  where num % 2 == 0
  select num;

Task Parallelism in .NET Framework 4
Altough we can achieve Task Parallelism using our traditional multi-threading approaches but  the new Task Parallel Library in .NET Framework 4 offers a lot than the ThreadPool. For simple scenarios, we can use Parallel.Invoke() that takes a variable number of delegates and executes them in parallel. For a fine-grained control, we can use the Task class and even the Task Scheduler. The rich set of APIs for Tasks support waiting, cancellation, continuations, robust exception handling, detailed status, custom scheduling, and much more.

//invoke some methods in parallel
Parallel.Invoke(
  Method1,
  Method2,
  Method3,
  () => { Debug.WriteLine("inline method"); }
);

//control passes here after "ALL" methods have invoked, thus preserving sequential semantics

Optimized Data Structures for Parallel Applications
The good things don’t end here. To assist parallel programming, we have got a whole bunch of new data structures that include concurrent collections, lightweight synchronization primitives, and types for lazy initialization.

I hope this post succeeds to create some temptation to look into the new parallel features in .NET Framework 4. Notice that since the syntax and semantics are much similar to the sequential style, it is very easy to parallelize a loop or invoke some methods concurrently. A very nice advantage of these parallel programming features is scalability, so if we introduce parallelism in our applications today, we can expect even more speed in the future when there are more number of cores. Finally, make sure to bookmark MS Parallel Team Blog and Reed’s series for related stuff. Happy Parallelizing!

Advertisements

9 Responses to “A brief overiew of the new Parallel Extensions in .NET Framework 4”

  1. DotNetShoutout Says:

    A brief overiew of the new Parallel Extensions in .NET Framework 4 « Mehroz’s Experiments…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. peteohanlon Says:

    Good job. I like this article.

  3. owen Says:

    Now this article begs the question; what can and can you do in the parrellel.for? especially since the program flow is locked until it is finished. Hopefully in .Net version 5 these features are implemented in the LANGUAGE instead of hacked into wrapper classes.

  4. Syed Mehroz Alam Says:

    Owen,

    The advantage lies in the fact that all iterations of the loop can be executed in parallel, and the advantage of blocking the flow until all the iterations are completed is to simplify the synchronization as it would be required in most of the cases. Of course, if we don’t want the blocking behavior of Parallel.For, we can always start the loop in a new Task.

  5. stromtarife vergleich Says:

    Keep up the good work. I just added your RSS feed
    I just wanted to drop you a comment to say keep up da good work.

  6. search Says:

    What’s up to all, how is all, I think every one is getting more from this web site, and your
    views are pleasant for new visitors.

  7. Judy Neistein Toronto Canada Says:

    For the reason that the admin of this web page is working, no question very shortly it will be famous, due to its quality contents.

  8. Judy Neinstein 201 Says:

    Hey There. I found your blog using msn. This is a very well written article.
    I’ll be sure to bookmark it and come back to read more of your useful information. Thanks for the post.

    I’ll certainly return.

  9. https://plus.google.com Says:

    My brother suggested I may like this blog. He used to be entirely
    right. This post actually made my day. You cann’t believe simply
    how so much time I had spent for this info!
    Thank you!


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

%d bloggers like this: