Параллельные вычисления в .Net 4.0
В связи с тем, что производители процессоров отошли от концепции производства все более и более мощных процессоров с 1 ядром, а делают ставку на мультипроцессорные системы, вопрос паралеллизации стает все более и более актуальным для разработчиков.
.Net 4.0 представляет нам широкий спектр инструментов для разработки паралельных аппликаций. Инструментарий называется просто – parallelization enhancements (PE).
Весь PE может быть разделен на 5 основных частей:
1. Task Parallel Library (TPL)
2. Parallel LINQ (PLINQ)
3. Инструменты для дебаггинга и профайлинга
4. Дата структуры координации
5. Parallel Pattern Library (PPL) (только С++).
Почему нам нужен parallelization enhancements?
Да, действительно, зачем нам все это нужно? Ведь можно просто создать кучу потоков, и радоваться мультипоточности.
Но:
1. Создание потока – очень ресурсоемкая операция. Создание большого количества потоков может причинить торможение Вашей аппликации.
2. Многие сейчас скажут: ну а как же пул потоков? Пул потоков решает большое количество проблем с торможением потоков, но опять же – но: пул потоков практически ничего не знает про работу которую исполняет тот или иной поток, потому запланировать работу кучи потоков – достаточно тяжелое занятие.
Разница между мультипоточностью и паралеллизмом.
Вот собственно и все. В мультипоточности может быть использовано 1 ядро, потому как операционная система использует 1 ядро, и очень быстро переключается между потоками. При паралельности потоки выполняются одновременно.
В первой стать , я для примера взял паралельные циклы:
Parallel.For()
Parallel.ForEach()
Для того, чтобы показать каков возможен прирост, будет использован следующий код:
Обычный For:
Stopwatch sw = new Stopwatch();
string str = string.Empty;
sw.Start();
//тут мы специально не используем стрингбилдер чтобы показать более - менее большие числа
for (int i = 0; i < 100000; i++)
{
str += i.ToString();
}
sw.Stop();
Console.WriteLine(sw.Elapsed.ToString());
Результат:00:00:37.9905721
Parallel For:
Stopwatch sw = new Stopwatch();
string str = string.Empty;
sw.Start();
Parallel.For(0, 100000, i =>
{
str += i.ToString();
});
sw.Stop();
Console.WriteLine(sw.Elapsed.ToString());
Результат: 00:00:06.6204853
Машина на которой вся эта радость тестилась: Core2Duo(2.66),3GB RAM, Windows7.
Результат впечатляет! На 4 ядерном скорость скорее всего будет ещё больше. И что самое приятное компилятор сам анализирует запрос и разделяет его на несколько паралельных потоков.
На этом пока все. В последующих статьях мы обязательно рассмотрим параллельные вычисления глубже.
P.S: Господа, огромный респект и уважуха тем кто поможет прикрутить подсветку синтаксиса!
P.S.S: Юра Опрышко, спасибо за помощь, и то что ты меня тыкнул в мою невнимательность:)