Overview
Microsoft Parallel Extensions to the. NET Framework 3.5 is a managed programming model for data parallelization and task parallelization. It can also coordinate Parallel hardware under a common job scheduler. Parallel Extensions to. NET Framework 3.5 makes it easier for developers to compile programs that give full play to the advantages of parallel hardware. It not only improves performance with the increase in the number of processors, but also avoids the complexity of many old concurrent programming models.
You can download Microsoft Parallel Extensions to the. NET Framework 3.5 June 2008 CTP from here. After installation, a System. Threading. dll assembly will be registered to GAC. Parallel Extensions consists of two parts: Task Parallel Library (TPL) and Parallel LINQ (PLINQ), which will be integrated into. NET Framework 4.0.
Simple call
Before starting, let's stop and think about several issues: if multiple threads access the same variable at the same time, they may affect each other. How can this problem be solved? If multiple threads lock some resources at the same time and cause deadlocks due to mutual wait, how can this problem be solved? If you think these problems are difficult to solve, don't think about them. With Parallel. Invoke, you don't have to worry about these headaches. Let's first define three tasks:
private void Task1(){ Thread.Sleep(1000);}private void Task2(){ Thread.Sleep(2000);}private void Task3(){ Thread.Sleep(3000);}
To call these three tasks in parallel, you only need one sentence:
Parallel.Invoke(Task1, Task2, Task3);
In addition, you can place all the tasks in an Action data group before calling them. The following code snippets are useful in some scenarios, in the design phase, we do not need to consider how many tasks will be executed during the final run:
Action[] actions = { Task1, Task2, Task3 };Parallel.Invoke(actions);
Perform a simple test on Parallel. Invoke, as shown in the following code snippet:
private long InvokeSequential(){ Stopwatch watch = new Stopwatch(); watch.Start(); Task1(); Task2(); Task3(); watch.Stop(); return watch.ElapsedMilliseconds;}private long InvokeParallel(){ Stopwatch watch = new Stopwatch(); watch.Start(); Parallel.Invoke(Task1, Task2, Task3); watch.Stop(); return watch.ElapsedMilliseconds;}private long InvokeParallelArray(){ Stopwatch watch = new Stopwatch(); watch.Start(); Action[] actions = { Task1, Task2, Task3 }; Parallel.Invoke(actions); watch.Stop(); return watch.ElapsedMilliseconds;}
To see the final result:
Loop call
Loop execution should be a problem we often encounter in programming, but all previous loops can only be executed in sequence, as shown in the following code:
for (int i = 0; i < 10; i++){ Compute(i);}
In Parallel Extensions, you can use Parallel. For Parallel execution of cyclic tasks:
Parallel.For(0, 10, delegate (int i){ Compute(i); } );
Even with Lambda expressions, you can simply write them as follows:
Parallel.For(0, 10, i => { Compute(i);} );
Now let's do a simple test with the Code as follows:
private static long SequentialForLoop(){ Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 10; i++) { Compute(i); } watch.Stop(); return watch.ElapsedMilliseconds;}private static long ParallelForLoop(){ Stopwatch watch = new Stopwatch(); watch.Start(); Parallel.For(0, 10, i => { Compute(i);} ); watch.Stop(); return watch.ElapsedMilliseconds;}private static void Compute(int i){ Thread.Sleep(200 * i);}
The test results are as follows:
Similar Parallel. ForEach methods are also provided in Parallel, as shown in:
We use code similar to the following to use this method:
List<int> data = new List<int> { 1, 2, 3, 4, 5 };Parallel.ForEach( data, i => { Compute(i); } );
Summary
The preceding section briefly introduces Parallel in the Task Parallel Library, hoping to help you.