Non-Destructive Me

Using PLINQ to Speed Up CPU Bound Operations - Demo

Coding for parallelism is never easy.  Keeping track of threads, synchronisation issues and locking is incredibly hard.  We've all had code where instantly we can see that running it in parallel would significantly improve the speed.  But the overhead of making sure everything runs properly without any issues normally keeps us developers away.

Introducing PLINQ.  In a nutshell it allows us to say what we need to be done instead of how we want it to be done.  PLINQ simply builds on LINQ with extra extension methods, in this case AsParallel(). You can build your entire expression tree and simply add AsParallel() to the end which tells the runtime to run the jobs in the query in parallel.

When I say run the query in parallel, this is not totally true.  The runtime determines which jobs it can run in parallel and how this will be accomplished

Johan and I cooked up a magical example today to show this in action.  An easy example is calculating if a specific number is prime or not and perfectly suited for a parallel execution.  We've attached the code so you can run this on your machine but an explanation is helpful.

Our code is very simple.  We build up a list of numbers to check and run them both through a parallel execution test and a sequential execution test and time them both.   We also run through different upper limits of the number list to test if parallel execution is faster in all instances; and it isn't.

So, on to the code.  The full code in the link below so I'll  show you the important parts, mainly the sequential test and the parallel test.

private long RunSequentialTest(List<PotentialPrime> numbersToCheck)
{
   Stopwatch watch = new Stopwatch();
   watch.Start();
 
   foreach (PotentialPrime num in numbersToCheck)
   {
         var q = IsPrime(num.Value);
         num.IsPrime = q;
   }
   return watch.ElapsedMilliseconds;
}

As you can see above, the method receives a list of numbers to check. We loop over the numbers, calling into a method called IsPrime() and sets the IsPrime property on the number.  Pretty simple to do and quite fast to run.

The parallel method is a little different.

private long RunParallelTest(List<PotentialPrime> numbersToCheck)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
 
    Parallel.ForEach(numbersToCheck, num =>
    {
        var q = IsPrime(num.Value);
        num.IsPrime = q;
 
    });
 
    return watch.ElapsedMilliseconds;
}
 
 

Instead of calling foreach normally, the new class Parallel class gives us a static method to use.  This will run the query we build in a parallel way if possible.  The expression is essentially the same as the sequential test code-wise but should be executed faster ( in certain circumstances).

If you run the code, we do see times that the sequential operation is faster.  This occurs in small numbers to check as there is an overhead of setting up and tearing down the threads so the parallel test does suffer.  In my tests on a single core, single CPU intel, the moment we hit 5000 numbers to check, the parallel execution won hands down.

This is pretty interesting stuff and PLINQ is still in its infancy so we should see some cool stuff coming from Microsoft around this area.  With the proliferation of multi-core CPUs in computers today, having an easy way to parallelise your code in .NET or in any language is now a necessity.  Have fun!

 

Prerequisites:

Visual Studio 2008 RTM

.NET 3.5

PLINQ December 2007 CTP

 

Example Code:

Download here

Posted: 01-18-2008 12:02 by Ray Booysen | with 3 comment(s)
Filed under: , ,

Comments

Michael Corent said:

There is an excellent book, recently published by Birmingham's publisher Packt Publishing - www.packtpub.com

"C# 2008 and 2005 threaded programming", by G. HILLAR.

It explains everything an ordinary C# developer should know to exploit multicore processors.

Great book, simple and easy to understand.

Amazon link (UK): http://www.amazon.co.uk/2008-2005-Threaded-Programming-Beginners/dp/1847197108/ref=pd_rhf_p_t_1

# February 9, 2009 9:10 PM

Gunnar said:

Thanks for cool demo. I just wanted to let you know that I will use this demo in my presentation.

# January 12, 2010 7:56 PM

Gunnar Peipman's ASP.NET blog said:

I one of my sessions I demonstrated how PLINQ uses two CPU-s instead of one and has better performance

# January 31, 2010 3:49 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)