Multi-core processorsadvanced a lot and are being used in mobile phones and
PDAs today. To harness these multi-core capabilities, developers need to
parallelize their code. Microsoft Visual Studio 2010 and .NET Framework 4.0 Beta
1 are filled with features to help developers write efficient code for
multi-core machines and that too without drilling deep to thread level. Parallel
programming support in latest version of VS comprises of following features:
- Task Parallel Library (TPL), for implementation of 'For' and 'ForEach'
loop which in turn help in defining concurrent tasks - Data structures for parallel programming
- Parallel diagnostic tools which include debugger window for tasks and
parallel tasks - PLINQ -the parallel implementation of LINQ. PLINQ can be used to enhance
performance where one needs to process large sets of data like trade analysis,
scientific computing etc.
PLINQ
Parallel Language Integrated Query (PLINQ) is the parallel implementation of
LINQ to objects. PLINQ combines the simplicity and readability of LINQ syntax
with the power of parallel programming. Based on the capability of host
computer, PLINQ queries parallelize themselves. Executing queries using PLINQ is
similar to the way queries are executed with LINQ. All the operators supported
by 'System.Linq.Enurmables' can be used in writing PLINQ queries. One point to
note here is that, LINQ-to-SQL and LINQ-to-Entities cannot be parallelized as
these queries would still be executed by respective databases. Writing a PLINQ
query is similar to writing LINQ query with addition of two simple steps. First
one needs to add reference to 'System.Threading.dll' assembly during
compilation, then wrap data source around the 'IParallelEnumerable
using a call to the 'AsParallel' extension method. 'AsParallel' method instructs
compiler to use 'IParallelEnumerable
some sample PLINQ code that displays all the numbers between 1 to 1000 that give
zero reminder after division with 10. We have written this code using Visual
Studio 2010 and used C# as programming language:
Direct Hit! |
Applies To: .NET Developers USP: Learn parallel programming Primary Link: www.msdn.com Keywords: PLINQ |
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string<> args)
{
var source = Enumerable.Range(1, 1000);
var parallelQuery = from num in source.AsParallel()
where num % 10 ==0
select num;
} } }
This diagram depicts different components of parallel programming architecture of .NET Framework 4 Beta 1. |
The output of the sample PLINQ query run on a quad core machine. Output is not in order as processing is done in parallel. |
Output Processing
Like LINQ, PLINQ also has deferred execution, parallelism does not get
introduced until output is processed. There are three ways to process output in
PLINQ. In the pipeline processing model, thread doing enumeration is separated
from the threads running query. This means if your machine has n processors then
n-1 would be used for running PLINQ query and 1 would be used to run 'foeach'
loop on output of PLINQ query. Here is the sample code that processes output of
the above PLINQ query:
foreach (var q in parallelQuery)
{
Console.WriteLine(q);
}
This output shows exception handling in PLINQ. As machine was quad-core, output elements are displayed along with exception. |
Second processing model is stop-and-go processing. In this model, the thread
that starts enumeration joins all the other threads to execute PLINQ query. And
once all threads have finished processing query, the thread then moves to
enumerating output. Finally there is inverted enumeration model, here a lambda
function is provided to PLINQ that is run in parallel, once for each in element
in the output. To use this output processing model, special 'ForAll' API is
used. Here is the sample code that processes output of above PLINQ query:
parallelQuery.ForAll(q => Console.WriteLine(q));
Exception handling
As queries are executed in parallel, there is a different mechanism of handling
exceptions in PLINQ. Consider the following code snippet:
string<> arrStr = new
string<>{"1","2","g","3","4","5","6","7","8","9",""};
var query = from a in arrStr.AsParallel()
select int.Parse(a);
query.ForAll(q => Console.WriteLine(q));
This snippet should throws two exceptions, but, as query is processed in
parallel depending on the number of processors in your machine, you might get
different exceptions in different order. When an exception occurs in a thread,
PLINQ tries to stop all other threads as quickly as possible. Once all threads
are stopped, PLINQ aggregates all exceptions into a new
System.Threading.AggregateException
and throws it. These exceptions are available as inner exceptions along with
their stack trace. Besides making application run faster, PLINQ also enables you
to do more computation on large data set in given amount of time.