пятница, ноября 30, 2007

Вчера вышел Parallel FX CTP

"Даешь параллельный код в программерские массы" - примерно такой лозунг бросил Херб Саттер (Herb Sutter) в своей статье "Программное обеспечение и параллельная революция" почти два года назад. И нам стало ясно, что в недрах Microsoft Research готовится что то интересное. Если раньше параллельное программирование было уделом суровых парней с широкими лбами в лабораториях Intel, то сейчас, стараниями того же Intel-а мы все стоим перед фактом, что без распараллеливания кода все наши новые программы окажутся на помойке.
Но близок тот день, когда любой рязанский паренек вместо


for (int i = 0; i < 100; i++)
{
a[i] = a[i]*a[i];
}


станет писать


Parallel.For(0, 100, delegate(int i) {
a[i] = a[i]*a[i];
});


и не будет делать круглые глаза при словах декларативный параллелизм.
А близок он по тому, что уже вышел первый CTP .Net библиотеки Parallel FX. Как пишет в своем блоге Джо Даффи, Parallel FX теперь можно взять здесь и потрогать руками.
В будущем он войдет в состав .Net Framework в виде библиотеки System.Concurrency и расширений Parallel LINQ, и, я надеюсь, станет таким же привычным как System.Threading или System.Net.
Для тех кому интересно, что там внутри - ссылки:
"Оптимизация управляемого кода для многоядерных компьютеров" - описание возможностей Parallel FX в MSDN Magazine (на русском).
"Параллельный LINQ: Выполнение запросов на многоядерных процессорах" статья о PLINQ в MSDN Magazine (на русском).

7 комментариев:

Илья Казначеев комментирует...

Parallel.For(0, 100, delegate(int i) {
a[i] = a[i]*a[i];
});


In that unhappy scenario, this Java code:
// print even numbers from 2 to 100
for (int i = 2; i <= 100; i += 2) {
System.out.println(i);
}
would instead look like this:
// print even numbers from 2 to 100
LoopObject loop = new LoopObject();
loop.setStartingValue(2);
loop.setEndingValue(10);
loop.setCounterIncrement(2);
loop.setOperation(new LoopBody() {
public void loopBody(int currentIndex) {
System.out.println(currentIndex);
}
});
loop.start();
(c) Steve Yegge, Language trickery and EJB
http://steve.yegge.googlepages.com/language-trickery-and-ejb

Sergey Rozovik комментирует...

> would instead look like this: ....
Еще раз убеждаемся насколько круто: вместо for - Parallel.For, а не куча кода.
Сегодня C# на полкорпуса впереди. Но Java подтянется. Я верю.

Илья Казначеев комментирует...

Здесь все полкорпуса заключаются в наличии делегатов.
Делегаты - это хорошо, спору нет, хотя и хвастаться тут особо нечем - другие языки это имели лет за 10 до C#.

По хорошему, это должно писаться так:

[Parallel]
for (int i = 0; i < 100; i++)
{ ... }

Меняем на @Parallel для java.
Но пока они допустят аннотации в святая святых - тела методов и вешание-на-кейворды, пройдет и правда пара геологических эпох.

Sergey Rozovik комментирует...

>По хорошему, это должно писаться >так:
>[Parallel]
>for (int i = 0; i < 100; i++)
Так тоже можно. Правда атрибут Parallel не может быть применен к оператору, а вот к методу - запросто.
Но дело в том, что Parallel.For() гораздо эффективней, поскольку обрабатывается на этапе компиляции, а аттрибутивная метаинформация типа [Parallel] обрабатывается в runtime.

Илья Казначеев комментирует...

Так в том и дело - надо разрешить применять атрибуты к операторам цикла и объявлениям переменных внутри метода. Это будет тот путь, по которому пошло OpenMP.

В случае Parallel.For не всё так просто - например, судя по вашему примеру, delegate {} создает замыкание, в котором хранится ссылка на массив a?
Однако надо иметь в вижу, что с переменными внутри распараллеливаемого цикла можно делать далеко не всё, причем набор ограничений не задан умной книжкой, а определяется на этапе программирования и здорово влияет на эффективность и надежность кода.
В следующий раз наш начинающий гений параллельного программирования напишет Parallel.For(0, 100, delegate(int i) {
a[i] = a[i]*a[i + 1];
});
И программа его встанет в позу.
Или, что самое страшное, не встанет у него, зато встанет через год у пользователя. Потому, что язык никак не может проверить, правильно ли он работает с параллельным программированием.

Гораздо проще научить программистов Erlangу, чем заставить проверять допустимость и корректность всех обращений к переменным в каждом используемом цикле. Стив и об этом писал, на самом деле.

Андрей Крылов комментирует...

Возможно будет интересно ознакомиться с Parallel C#. Там по-моему интереснее всё сделано, правда пока ещё сыроват проект, но может доделают его когда-нить...

Sergey Rozovik комментирует...

to Андрей Крылов

Да, действительно интересно. Странно, что на страничке нет никаких реквизитов о том, чьи это исследования.
Дело в том, что Parallel C# полностью базируется на MC# (насколько я понял добавлены только синтаксические возможности из C# 3.0, которых не было на момент разработки MC#). Ну а MC# это разработка ребят из ИПС РАН в Переяславле :)