- podział zadań na Taski
- wykonywanie Tasków na wątkach
- zebranie wszystkich wyników w całość
static void PrimeNumbers() { IEnumerable<int> numbers = Enumerable.Range(3, 100000 - 3); var parallelQuery = from n in numbers.AsParallel() where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i > 0) select n; int[] primes = parallelQuery.ToArray(); foreach (var prime in primes) { Console.Write("{0} ", prime); } }
Zapytania PLINQ, podobnie jak każde inne LINQ są wykonywane z opóźnieniem, w momencie, gdy np. wywołamy ToArray, pętlę foreach itd. Równoległość obliczeń powoduje jednak, że wyniki będą nieuporządkowane. Jeżeli zależy nam na tym, by wynik wyglądał tak, jak w sekwencyjnym zapytaniu, możemy dodatkowo wywołać metodę AsOrdered()
from n in numbers.AsParallel().AsOrdered()
Wywołania takie wpływa oczywiście na pogorszenie wydajności, dlatego takie zachowanie nie pojawia się domyślnie.
PLINQ optymalizuje zrównoleglenie pod kątem możliwości sprzętowych. To jedna z największych zalet zwłaszcza pod kątem przyszłości, gdzie liczba rdzeni w komputerach PC będzie ciągle wzrastać. W przypadku niektórych komputerów, PLINQ może wykonać obliczenia sekwencyjnie pomimo użycia AsParallel(), np. dlatego, że zrównoleglenie może pogorszyć wydajność. Programista ma możliwość wymuszenia równoległości instrukcją
from n in numbers.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism)
Kolejną ciekawą instrukcją jest WithDegreeOfParallelism(), gdzie podajemy ilość Tasków, na których ma być przetwarzane zapytanie. Szczególnie przydatne jest to w przypadku odpytywania WebSerwisów, gdzie tracimy czas nie na obliczeniach na CPU, ale na oczekiwaniu na odpowiedź.
from n in numbers.AsParallel().WithDegreeOfParallelism(6)
Brak komentarzy:
Prześlij komentarz