Parallel Class Trong C# và Vấn Đề Xử lý Song Song


Hôm nay chúng ta sẽ tìm hiểu về cơ chế xử lý song song trong C# với Parallel Class. Nhiều máy tính cá nhân và máy trạm có hai hoặc bốn lõi (CPU) cho phép nhiều luồng xử lý (Thread) được thực hiện đồng thời. Máy tính trong tương lai gần dự kiến ​​sẽ  còn có nhiều hơn số lỗi hiện tại. Để tận dụng lợi thế của phần cứng của ngày hôm nay và ngày mai, bạn có thể phân phối công việc trên nhiều luồng xử lý trên nhiều lõi. Visual Studio 2010 và .NET Framework 4 hỗ trợ tăng cường cho lập trình song song bằng cách cung cấp một runtime mới, các loại thư viện lớp mới, và các công cụ chẩn đoán mới. Những tính năng đơn giản hóa phát triển song song để bạn có thể viết hiệu quả, khả năng mở rộng và đa dạng tiến trình song song.




Khi Nào Nên Dùng Lớp Parallel


Kiểm Tra Tốc Độ Của Foreach vs LinQ vs LinQasParallel


Hình minh họa dưới đây cung cấp một cái nhìn tổng quan cấp cao của kiến ​​trúc lập trình song song trong .NET Framework 4




[caption id="" align="aligncenter" width="672"]Phạm Tuân C# parallel Phạm Tuân[/caption]

Các bạn có thể tham khảo thêm chủ đề liên quan đến vấn đề này qua bản dưới.


















































TechnologyDescription
Task Parallel Library (TPL)Provides documentation for the System.Threading.Tasks.Parallel class, which includes parallel versions of For and ForEach loops, and also for theSystem.Threading.Tasks.Task class, which represents the preferred way to express asynchronous operations.
Parallel LINQ (PLINQ)A parallel implementation of LINQ to Objects that significantly improves performance in many scenarios.
Data Structures for Parallel ProgrammingProvides links to documentation for thread-safe collection classes, lightweight synchronization types, and types for lazy initialization.
Parallel Diagnostic ToolsProvides links to documentation for Visual Studio debugger windows for tasks and parallel stacks, and the Concurrency Visualizer, which consists of a set of views in the Visual Studio Application Lifecycle Management Profiler that you can use to debug and to tune the performance of parallel code.
Custom Partitioners for PLINQ and TPLDescribes how partitioners work and how to configure the default partitioners or create a new partitioner.
Task FactoriesDescribes the role of the System.Threading.Tasks.TaskFactory class.
Task SchedulersDescribes how schedulers work and how the default schedulers may be configured.
Lambda Expressions in PLINQ and TPLProvides a brief overview of lambda expressions in C# and Visual Basic, and shows how they are used in PLINQ and the Task Parallel Library.
For Further Reading (Parallel Programming)Provides links to additional documentation and sample resources for parallel programming in the .NET Framework.
Advanced Reading for the .NET FrameworkTop level node for advanced topics such as threading and parallel programming.

Cách khai báo và sử dụng lớp Parallel trong C#.




[code language="csharp"]
//Cách dùng for bình thường ta vẫn hay dùng
int n = ...
for (int i = 0; i < n; i++)
{
// ...
}

//Cách dùng với lớp parallel
int n = ...
Parallel.For(0, n, i =>
{
// ...
});

//Hoặcvới một IEnumerable

IEnumerable<MyObject> myEnumerable = ...

Parallel.ForEach(myEnumerable, obj =>
{
// ...
});
[/code]

Vẫn có thể dùng với LINQ




[code language="csharp"]
IEnumerable<MyObject> source = ...

// LINQ
var query1 = from i in source select Normalize(i);

// PLINQ = parallel LINQ
var query2 = from i in source.AsParallel()
select Normalize(i);
//Hoặc
IEnumerable<MyObject> myEnumerable = ...

myEnumerable.AsParallel().ForAll(obj => DoWork(obj));
[/code]

Lợi ích trước mắt chúng ta có thể nhận thấy đó là tốc độ và thời gian được cải thiện đáng kể, hãy xem xét ví dụ sau đây.




[code language="csharp"]
class Program
{
//Tính tổng
static int SumDefault(int[] array)
{
return array.Sum();
}

//Tính tổng với Parallel
static int SumAsParallel(int[] array)
{
return array.AsParallel().Sum();
}

static void Main()
{
// Tạo mảng.
int[] array = Enumerable.Range(0, short.MaxValue).ToArray();

// Test methods.
Console.WriteLine("Result for Parallel: " + SumAsParallel(array));
Console.WriteLine("Result for None-Parallel: " + SumDefault(array));

const int m = 10000;
var s1 = Stopwatch.StartNew();
for (int i = 0; i < m; i++)
{
SumDefault(array);
}
s1.Stop();

var s2 = Stopwatch.StartNew();
for (int i = 0; i < m; i++)
{
SumAsParallel(array);
}
s2.Stop();
Console.WriteLine("\nTime for None-paralel: "
+ ((double)(s1.Elapsed.TotalMilliseconds * 1000000) / m).ToString("0.00 ns"));

Console.WriteLine("Time for Paralel: "
+ ((double)(s2.Elapsed.TotalMilliseconds * 1000000) / m).ToString("0.00 ns"));

Console.Read();
}
}
[/code]

Các bạn có thể tìm hiểu thêm về parallel thông qua cuốn sách này - Parallel Programming with Microsoft .NET


Chúc các bạn thành công!


Phạm Tuân


Chúc các bạn thành công!
PHẠM TUÂN