command-style data parallelism
Visual C # 2010 and. NETFRAMEWORK4.0 offers many exciting new features that are designed to deal with the complexities of multicore processors and multiprocessor. However, since they include complete new features, developers and architects must learn a new programming model.
This chapter is a new class, struct, and enumeration type that you can use to handle data parallelism scenarios. This chapter will show you how to create parallel code and describe the new concepts associated with each scenario, rather than focusing on the most complex issues in concurrent programming. This way you will be able to understand performance improvements more fully.
Start a parallel task
Using the previous version of the. NET Framework, it is difficult to develop applications that can take advantage of the parallel capabilities of multicore microprocessors. It is necessary to start, control, manage, and synchronize multithreading using complex structures that control parallelism, but this is not very effective for modern multicore systems.
. NET 4 introduces a new Task Parallel library (TPL), which is produced in the multicore era and is the lightweight concurrent programming model shown in Chapter one.
To support data parallelism, task parallelism, and pipelines, TPL provides a lightweight framework that helps developers cope with different parallel scenarios, implement task-based design, and not work with heavy-weight threads. These scenarios include
Data parallelism
There is a lot of data, and every piece of data has to do the same thing. 2-1, encrypt 100 Unicode strings using the 256-bit key AES algorithm.
Figure 2-1 Task parallelism
There are many different operations that can be executed in parallel, leveraging the power of parallelism. For example, generate a hash encoding of the file, encrypt the Unicode string, and create a thumbnail image of the picture. 2-2,
Figure 2-2 Pipeline
This is a mix of task parallelism and data parallelism. This is the most complex scenario because it always needs to coordinate multiple specific concurrency tasks. For example, encrypt 100 Unicode strings with an AES algorithm that uses a 256-bit key, and then produce a hash value for each encrypted string. This pipeline enables simultaneous execution of two concurrent cryptographic and hash code generation tasks. Each encrypted Unicode string is placed in the queue in order to be processed using a hash-coding algorithm. 2-3,
Figure 2-3
Of course there are complex scenarios that mix all the situations in front of you. The easiest way to understand how to work with parallel tasks is to use them. The following chapters will cover these most common scenarios using detailed examples.
TPL introduces a new namespace, System.Threading.Tasks. This namespace can be accessed. The new class, struct, and enumeration types introduced by NET4. So, whenever you want to use TPL, it's a good idea to use this namespace.
Using System.Threading.Tasks;
This way you can avoid a lot of references. For example, you can use Parallel.Invoke instead of using System.Threading.Tasks.Parallel.Invoke.
The primary class is the task, which represents an asynchronous concurrency operation. However, it is not necessary to use the instance of a task directly in order to create parallel code. Sometimes, the best option is to create parallel loops and regions. In these scenarios, you can work with the methods provided by the static class parallel, rather than using the lower-level task instance.
The parallel.for---provides a potential parallel execution of load balancing for a fixed number of independent for loop iterations.
The Parallel.ForEach---provides a potential parallel execution of load balancing for a fixed number of independent for Each loop iterations. This method supports custom partitioning classes, which gives you complete control over the distribution of the data.
Parallel.invok---Provides potential parallel execution of independent tasks.
Load balancing execution attempts to distribute work across different tasks so that all tasks can remain busy for most of the time. Load balancing always tries to reduce the idle time of the task.
These methods are useful when refactoring existing code to take advantage of potential concurrency benefits. However, it is important to understand that it is not as simple as using parallel.for instead of for.
Parallel.Invoke
The simplest way to try to parallelize many methods is to use the Invoke method provided by parallel. Here is the. NET in the parallel invoke function prototype. Invoke accepts no return value (or the return value is void) action[] parameter array to parallelize the operation as much as possible.
public static void Invoke (params action[] actions);////<summary>///performs each operation provided and runs as much as possible, unless the user cancels the operation. </summary>
The following four functions are available:
static void First () { System.Console.WriteLine ("1--first"); } static void Second () { System.Console.WriteLine ("2--second"); } static void third () { System.Console.WriteLine ("3--third"); } static void fourth () { System.Console.WriteLine ("4--fourth"); }
Perform the above four functions in parallel using the parallel invoke function.
Parallel.Invoke ( () = First (), () = Second (), () = third (), () = fourth ());
The above call () =>first () is in the form of a lambda expression. You can also use anonymous delegates to execute the above code, as shown in the following code.
Parallel.Invoke ( delegate {first ();}, delegate {Second ();}, Delegate {third ();}, delegate {fourth ( ); });
or pass in the function arguments directly, as shown in the following code, but one of the advantages of using lambda expressions and anonymous delegates is that you can define a multiline method that requires parallel execution without the need to create additional methods.
Parallel.Invoke (First , Second, Third, fourth);
The output is:
First execution: 3-1-2-4
Second execution: 1-2-3-4
Third execution: 2-3-4-1
You need to pay special attention to the following two points when using the Invoke function of parallel: 1, function execution does not require a specific order. 2, function execution must be independent, there is no specific dependency.
Advantages and Tradeoffs
The key advantage of using Parallel.Invoke is that this is an easy way to run parallel methods without considering task and threading issues. However, invoke is not suitable for all situations. There are a couple of tradeoffs to consider:
If you use Parallel.Invoke to load a method that has a different run time, it takes a long time to return control. This allows many logical cores to be idle. Therefore, it is important to measure the results of the operation, the speedup of the implementation, and the utilization of the logical cores when using it.
has limitations in terms of parallel scalability. Because Parallel.Invoke calls a fixed number of delegates.
Each call to Parallel.Invoke has some extra overhead.
As with other parallel code, any correlation or uncontrolled interaction of different methods can lead to difficult-to-detect bugs and unexpected side effects.
The Parallel.Invoke method can be considered when there is no requirement for the execution order of the methods. Complex algorithms that require a specific order of execution are not suitable for using parallel. Invoke
Use parallel. In the Invoke parallel run method, the exception handling problem should be considered.
C # Parallel programming--imperative data parallelism (Parallel.Invoke)---understood with anonymous functions (reprinted)