System.Threading
library, which is called Parallel Extensions . This addition allows you to perform tasks on a high level on all available cores / processors.Parallel.For
, Parallel.Foreach
and Parallel.Invoke
to perform parallel computing. All work on creating and terminating threads, depending on the processors available, is performed by the library automatically.AsParallel()
at the beginning of the request so that all subsequent operators are executed in parallel. Internally uses TPL.public class Prime<br> {<br> /// <summary> <br> /// Determines whether the specified candidate is prime. <br> /// </summary> <br> /// <param name="candidate">The candidate.</param> <br> /// <returns> <br> /// <c>true</c> if the specified candidate is prime; otherwise, <c>false</c>. <br> /// </returns> <br> public static bool IsPrime( int candidate)<br> {<br> for ( int d = 2; d <= candidate/2; d++)<br> {<br> if (candidate%d == 0)<br> return false ;<br> }<br> return candidate > 1;<br> }<br> } <br><br> * This source code was highlighted with Source Code Highlighter .
interface IPrimeFinder<br> {<br> /// <summary> <br> /// Finds primes up to the specified limit. <br> /// </summary> <br> /// <param name="limit">The limit.</param> <br> /// <returns>List of primes</returns> <br> List < int > Find ( int limit );<br> } <br><br> * This source code was highlighted with Source Code Highlighter .
limit
:public List < int > Find( int limit)<br> {<br> var result = new List < int >();<br><br> for ( int i = 2; i < limit; i++)<br> {<br> if (Prime.IsPrime(i))<br> result.Add(i);<br> }<br><br> return result;<br> } <br><br> * This source code was highlighted with Source Code Highlighter .
Parallel.For()
method takes three parameters: the beginning of the interval, the end, and the delegate to execute. Note that the modification does not affect the body of the loop:public List < int > Find( int limit)<br> {<br> var result = new List < int >();<br><br> Parallel.For(2, //start from <br> limit, //up to <br> i => //action variable <br> {<br> if (Prime.IsPrime(i))<br> result.Add(i);<br> });<br><br> return result;<br> } <br><br> * This source code was highlighted with Source Code Highlighter .
List<T>
allows you to add elements in different threads. But if we tried to go through the list using foreach, we would get an error. All work with synchronization and lies on the user.Enumerable.Range ( 2, limit - 1 ).Where ( Prime.IsPrime ).ToList ( ); <br><br> * This source code was highlighted with Source Code Highlighter .
AsParallel()
:Enumerable.Range(2, limit - 1).AsParallel().Where(Prime.IsPrime).ToList(); <br><br> * This source code was highlighted with Source Code Highlighter .
AsParallel()
will be executed in parallel threads using all processors. As can be seen in the case of LINQ, no changes affecting the content of the source code were required. Moreover, this option is more secure in terms of threads: in this case, PLINQ itself synchronizes execution. You can also use aggregate functions.Parallel.Invoke()
is mainly used to perform versatile tasks. In our version, we divide all the numbers from the range into 10 parts and perform the calculation in the form of parallel tasks. To do this, create an additional helper method that takes as its arguments the upper bound, the number of subranges and the number of the subrange to be calculated:private static List < int > CheckRange( int n, int limit, int factor)<br> {<br> var local_result = new List < int >();<br> for ( int i = n*(limit/factor); i < (n + 1)*(limit/factor); i++)<br> {<br> if (Prime.IsPrime(i))<br> local_result.Add(i);<br> }<br> return local_result;<br> } <br><br> * This source code was highlighted with Source Code Highlighter .
Parallel.Invoke()
in our case takes an array of delegates. The new code will look like this:public List < int > Find( int limit)<br> {<br> var result = new List < int >();<br> Parallel.Invoke(() => result.AddRange(CheckRange(0, limit, 10)),<br> () => result.AddRange(CheckRange(1, limit, 10)),<br> () => result.AddRange(CheckRange(2, limit, 10)),<br> () => result.AddRange(CheckRange(3, limit, 10)),<br> () => result.AddRange(CheckRange(4, limit, 10)),<br> () => result.AddRange(CheckRange(5, limit, 10)),<br> () => result.AddRange(CheckRange(6, limit, 10)),<br> () => result.AddRange(CheckRange(7, limit, 10)),<br> () => result.AddRange(CheckRange(8, limit, 10)),<br> () => result.AddRange(CheckRange(9, limit, 10)));<br><br> return result;<br> } <br><br> * This source code was highlighted with Source Code Highlighter .
Source: https://habr.com/ru/post/45732/
All Articles