ENTERPRISE

Parallel Programming with Microsoft Visual Studio 2010 : Introduction to LINQ (part 2) - PLINQ

1/16/2014 12:06:39 AM

PLINQ

PLINQ is the parallel version of LINQ. The objective of parallel programming is to maximize processor utilization with increased throughput in a multicore architecture. For a multicore computer, your application should recognize and scale performance to the number of available processor cores. As shown earlier, the LINQ query executes when you iterate over the results, and it executes sequentially. With PLINQ, the iterations are performed in parallel, as tasks are scheduled on threads running in the .NET Framework 4 thread pool.

One of the best features of PLINQ is that it’s easy to convert LINQ queries to PLINQ. You can simply add the AsParallel clause.

from book in books where book.Publisher=="Lucerne Publishing"
orderby book.Title select book;

Now, here’s the same query updated for PLINQ. Note that the only addition to the code is the call to the AsParallel method of the books collection. This minor change, however, completely alters how the query is performed. When you iterate over the results, the query is performed with parallel tasks.

from book in books.AsParallel() where book.Publisher=="Lucerne Publishing"
orderby book.Title select book;

This next tutorial contrasts the productivity of standard LINQ and PLINQ. You can perform the example query either sequentially or in parallel. You’ll display information to compare the performance of both approaches. The task and thread identifiers are also displayed to highlight the underlying differences between parallel and sequential execution. Because the sequential version of the query does not use the Task Parallel Library (TPL), the task IDs are blank. In addition, the sequential version will execute on a single thread.

Perform a sequential query and a parallel query on an integer array, and imperatively invoke the Where clause

  1. Create a console application for C# in Visual Studio 2010. Add using statements for both the System.Threading and System.Diagnostics namespaces.

  2. Above the Main method, create a static method called Normalize that returns a bool. You’ll call this method in the Where clause. In the Normalize method, display the current task and thread identifiers. Use the Thread.SpinWait method to simulate a real-world normalization operation. Return true to select and add the current element to the result collection.

    static bool Normalize()
    {
    Console.WriteLine("Normalizing [Task {0} : Thread {1}]",
    Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
    Thread.SpinWait(int.MaxValue);
    return true;
    }
  3. In Main, create an instance of the Stopwatch class. The Stopwatch is used to calculate the duration of both the sequential and the parallel versions of the PLINQ query. Also, define an integer array that has four elements. This is the array you will query.

    Stopwatch sw = new Stopwatch();
    var intArray = new [] { 1, 2, 3, 4 };
  4. Perform a sequential query on the array by using LINQ to Objects. Call the Where method. Evaluate a lambda expression and call the Normalize method as a parameter. The Where method—and consequently Normalize—will be called for each element of the array. Because the lambda expression returns true for each element, all elements of the array are included in the results. On the next line, repeat the query but use PLINQ. Add the AsParallel method. For now, comment out the parallel version of the query. You will initially run only the sequential query.

    var result = intArray.Where((index)=>Normalize());
    //var result = intArray.AsParallel().Where((index) => Normalize());
  5. Start the Stopwatch, and then iterate the results of the query. Display the results of the operation. Because of deferred execution, this is when the query actually executes.

    foreach (int item in result)
    {
    Console.WriteLine("Item={0}", item);
    }
  6. Call the Stop method on the Stopwatch class and display the duration.

    sw.Stop();
    Console.WriteLine("Elapse time: {0}: seconds",
    sw.ElapsedMilliseconds / 1000);

Here is the entire program.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Performance
{
class Program
{
static bool Normalize()
{
Console.WriteLine("Normalizing [Task {0} : Thread {1}]",
Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
Thread.SpinWait(int.MaxValue);
return true;
}

static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
var intArray = new [] { 1, 2, 3, 4 };
var result = intArray.Where((index)=>Normalize());
//var result = intArray.AsParallel().Where((index) => Normalize());

sw.Start();
foreach (int item in result)
{
Console.WriteLine("Item={0}", item);
}
sw.Stop();
Console.WriteLine("Elapsed time: {0}: seconds",
sw.ElapsedMilliseconds / 1000);

Console.WriteLine("Press Enter to Continue");
Console.ReadLine();
}
}
}

Build and run the application. Because the statement containing the PLINQ query is commented, the code executes only the standard LINQ query. Each operation is therefore performed sequentially and on the same thread, which you can see from the output in the console window as shown in the following image. Because parallel tasks are not used, task IDs are not displayed. The duration is essentially the sum of running each of the operations in order.

PLINQ

Now uncomment the statement containing the PLINQ command and comment out the LINQ query instead. Rerun the application. This time, the results are entirely different. The Where method runs in parallel and on different threads, as shown in the output window in the following image. The PLINQ query leverages the multicore processor architecture; the results are specific to this example and the current hardware architecture. In this example, each iteration of a query operation is a different task. For this reason, the query runs faster.

PLINQ

The difference in performance of the two versions is depicted in Processor Utilization of the Task Manager. The next image shows a screen shot of processor utilization from the LINQ version of the application. In this example, average processor utilization is about 12 percent. Most of the processor computing capability is unused!

PLINQ

However, the PLINQ version of the application is much more efficient. In the following image, you can see a considerably higher utilization—more than 50 percent.

PLINQ
Other  
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 7)
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 6) - One-to-Many Joins - The join Operator
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 5) - One-to-One Join Performance Comparisons
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 4)
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 3)
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 2) - One-to-One Joins - The join Operator
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 1) - Cross Joins
  •  Moving into SAP Functional Development : Gaining Control of Change Control - How to Organize and Plan for Change in the Real World
  •  Moving into SAP Functional Development : Gaining Control of Change Control - Change Control and the SAP Solution Stack
  •  Moving into SAP Functional Development : Gaining Control of Change Control - Change Control Affects Everything
  •  
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    Popular Tags
    Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone