Нахождение простых чисел с использованием PLINQ в Visual Studio 2010

Источник: msug

В математике число называется простым, если оно делится только на 1 и себя.

Список первых двадцати пяти простых чисел выглядит таким образом:

2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97

Следующий код (с использованием LINQ) находит все простые числа от 2 до указанного числа max:

Func<int, IEnumerable<int>> primeNumbers = max =>
     from i in Enumerable.Range(2, max - 1)
     where Enumerable.Range(2, i - 2).All(j => i % j != 0)
     select i;

IEnumerable<int> result = primeNumbers(10);

foreach(int i in result)
{
  Console.WriteLine(i);
}

Если выполнить этот код, то получим в результате 4 простых числа в диапазоне от 2 до 10 включительно - {2, 3, 5, 7}.

Если у вас имеется компьютер с двухядерным процессором, то можно заставить выполняться ваши LINQ-выражения параллельно на двух ядрах. Для этого можно использовать технологию PLINQ, которая доступна в Visual Studio 2010. Для программиста процесс адаптации кода для работы на разных ядрах в данном очень простой - для этого необходимо использовать метод метод-расширение AsParallel() так, как это показано в следующем коде:

Func<int, IEnumerable<int>> primeNumbers = max =>
     from i in Enumerable.Range(2, max - 1).AsParallel()
     where Enumerable.Range(2, i - 2).All(j => i % j != 0)
     select i;

IEnumerable<int> result = primeNumbers(10);

Давайте рассмотрим, как влияет распараллеливание задачи на время работы. Для этого решим задачу нахождения простых чисел в диапазоне от 2 до 50000. Напишем следующий код:

IEnumerable<int> result = PrimeNumbers(50000);

Stopwatch stopWatch = newStopwatch();
stopWatch.Start();
stopWatch.Stop();
// Write time elapsed
Console.WriteLine("Time elapsed: {0}", stopWatch.Elapsed);

Результаты:

  • 1 ядро: 00:00:06.0252929
  • 2 ядра: 00:00:03.2988351

В результате мы получим все тот же результат, но за меньшее время (не в два раза, как это можно было бы предположить, так как еще нужно дополнительное время для инициализации потоков, поэтому для маленьких задач время параллельного выполнения может быть больше обычного).

В Visual Studio 2010 появилось новое окно "Parallel Stacks", в котором отображаются все потоки и задачи, а также дается информация о том, где эти потоки или задачи выполняются:

Prime Numbers PLINQ Parallel Stacks Window 

Можно увидеть, что каждый поток ответственный за свой диапазон чисел, в данном случае первый поток обрабатывает число 32983, а второй - 33073 и все это происходит в асинхронном режиме.

Кроме того, в Visual Studio 2010 появилось новое окно "Parallel Tasks", с помощью которого можно проводить отладку потоков и получить другую необходимую информацию:

Prime Numbers PLINQ Parallel Tasks Window 

Для более детального изучения PLINQ рекомендуется скачать Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4.


Страница сайта http://185.71.96.61
Оригинал находится по адресу http://185.71.96.61/home.asp?artId=24039