parallel

KOMP will conduct mid-term mid-term mid-term. KOMP will conduct mid-term mid-term mid-term mid-term mid-term. Parallel; 3. the same as 2. In parallel; Parallel, parallel, parallel, parallel, parallel, parallel, parallel, parallel, parallel, parallel Similar content; Analogy; To make parallel; And… Rival; And… Compared; And… similar

System.Threading.Tasks.Parallel

Parallel mainly provides the For and ForEach families of methods to process all items in Parallel. Both series of methods have several overloads, but these two are the most common and easiest to use

Parallel.For(int fromInclude, int toExclude, Action<int> body)

This method starts with fromInclude and ends with toExclude, loops through each number and executes the code in the body against it. As can be seen from the names of the parameters, these numbers include fromInclude, but do not include toExclude.

This is very similar to for(int I = fromine; i < toExclude; I ++) {body(I)}, but unlike the “for” statement, which iterates through each number sequentially, Parallel.For tries to process the numbers simultaneously as much as possible — it’s asynchronous, which means it’s unordered.

Let’s take a simple example

Parallel.For(0, 10, (i) => {
    Console.Write($"{i} ");
});
Console.WriteLine();

Here is one of its possible outputs (not certain because it is unordered)

0, 4, 8, 9, 1, 3, 5, 6, 2, 7

Parallel.ForEach<T>(IEnumerable<T>, Action<T>)

Parallel.For is asynchronous For, so Parallel. Foreach is asynchronous ForEach. I’ll do the same example, but I’ll change it a little bit

var all = new [] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Parallel.ForEach(all, (i) => {
    Console.Write($"{i} ");
});
Console.WriteLine();

The result is an unordered array of output from 0 to 9.

The point of parallelism is to handle time-consuming computations

Parallel.For and Parallel. Foreach are described above, but they are not as useful as the native For and ForEach. Purest syntactically, yes, but realize that the purpose of Parallel is parallelism, and the purpose of parallelism is to efficiently handle time-consuming computations. So, now we need to assume that a cost calculation exists…

Void LongCalc(int n) {Thread.sleep (n * 1000); }

If you use a for loop, you don’t need to run to know that the following code will take more than 6000 milliseconds.

for (int i = 1; i < 4; i++) {
    LongCalc(i);
}

But Parallel.For

Stopwatch watch = new Stopwatch();
watch.Start();
Parallel.For(1, 4, LongCalc);
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);

The answer is 3019, no surprise, parallel!

If need be every timebodyWhat happens to the evaluation results of the call

This takes it to a whole new level. After all, not everything needs feedback.

Now, a recursive call factorial algorithm is used to simulate the time calculation, even though it is not very time consuming, in order to keep the code simple, we do not choose too large a number. And then let’s say we need to compute the factorial of n numbers, so we need to compute the factorial of each number in parallel, and then add up the results. The code might look something like this

int CalcFactorial(int n)
{
    return n <= 2 ? n : n * CalcFactorial(n - 1);
}

int SumFactorial(params int[] data)
{
    int sum = 0;
    Parallel.ForEach(data, n => {
        sum += CalcFactorial(n);
    });
    return sum;
}

Give a few numbers to get the result:

Console.WriteLine($"sum is {SumFactorial(4, 5, 7, 9)}");

Guess what?

368064? Yes.

368064, but not always, sometimes you might get a 120, or a 5040, why??

Note “parallelism,” which means there are thread-safety issues. Plus = is not an atomic operation, so I need to change that

int SumFactorial(params int[] data)
{
    int sum = 0;
    Parallel.ForEach(data, n => {
        Interlocked.Add(ref sum, CalcFactorial(n));
    });
    return sum;
}

As you wish, you are right this time. The Interlocked class provides atomic operations for simple calculations that are well worth learning.

Having said that, what is needed is not a calculated result, but each individual result? Parallel is a bit out of place, so try parallelQuery, which comes from LINQ.

System.Linq.ParallelQuery<T>

IEnumerable

.AsParallel() can easily result in ParallelQuery

, which is an extension provided in LINQ. So start with the familiar and use ParallelQuery

to compute the factorial sum

int SumFactorial(params int[] data)
{
    return data.AsParallel().Select(CalcFactorial).Sum();
}

It’s very simple. Also familiar is Select(), which results in a ParallelQuery

and inherits from IEnumerable

. So, if you want each individual result, just drop the Sum() and replace it with toList () or toArray (), or even use it as an IEnummerable

.

This seems to touch on a new topic — parallel LINQ. LINQ is also compiled to run as a method call. Now that there is code for method calls, it is not easy to write a LINQ statement:

int SumFactorial(params int[] data)
{
    return (from n in data.AsParallel()
            select CalcFactorial(n)).Sum();
}