Pull to refresh

Comments 69

Отлично! Просто супер! Спасибо!
«многие программы до сих пор умеют использовать только одним» — тут ошибка, или «использовать только один», или «пользоваться только одним».
Не знал про такое, большое спасибо!
Полезная штука.
Хорошая статья. Сам кручу-верчу PE в тестовых целях. И удивительно, первый материал на русском языке на эту тему, который мне попался. :)

Microsoft готовит ещё одну интересную штуку для кластерных вычислений, называется Dryad. Их подход получается даже более универсальным, чем MapReduce от Google. Так что скоро будем параллелить не только между процессорами, но и между компами. :)
Скоро в мире будет один большой компьютер. И не надо будет домой покупать. Ведь если все компьютеры объединить, то мощности, которые сейчас простаивают с лихвой покроют все потребности на ближайшие несколько лет. =)
а потом злобные пираты отрежут океанический кабель и миллиарды человек останутся без работающих компьютеров :)
централизация нужна в меру :)
Это наоборот распределение. Из одного супер-компьютера получится два полусупер-компьютера. И так можно резать пока опять у каждого не останется по одному. :)

Я имел ввиду объединить имеющиеся.
а данные тоже хранить в полном объеме на каждом компьютере? ибо если разрезать то можно оттяпать кусок чего-нибудь интересного
:)
а щас то че мешает?
windows HPC server вышел. ставь и параллель, говорят его поднять легко)
Сейчас, как 20 лет назад на PC XT — любая задача решается самописным кодом. А будет по-человечески — мы пишем высокоуровневый код, машина сама его распаралеливает, распределяет, и собирает результаты.
Про такие вещи, как OpenMP и MPI программисты под .NET видимо не слышали :(
Ну OpenMP, вообще говоря, не панацея…
Во-первых, насколько мне известно, он только для C++ и Fortran.
Во-вторых, с помощью него не так просто распараллелить сложные алгоритмы. В частности, алгоритмы парадигмы «разделяй и властвую» (простой пример — быстрая сортировка), так просто не параллелятся…
Во-вторых, с помощью него не так просто распараллелить сложные алгоритмы.
А с помощью Parallel Extensions, которые судя по описанию аналогичны OpenMP, это будет сделать легче? Нет. Что я для себя извлёк из этого: кому действительно нужно было увеличить быстродействие — написали нужный кусок кода на C+OpenMP, а не ждали пока сделают подобное для .NET. Думаю вы, как человек явно разбирающийся в теме, согласитесь, что слышать в нынешнее время фразу
Так что скоро будем параллелить не только между процессорами, но и между компами. :)
довольно странно.
Да, я с Вами полностью согласен. Мне вообще не нравится идея писать на .NET хоть сколь-нибудь серьезные вычисления. Зато GUI я пишу только на нем.

Мой пост скорее о другом: что мир на OpenMP не сошелся и я, в частности, не сумел на нем решить свою задачу распараллеливания. Мне пришлось использовать относительно новую библиотеку Intel Threading Building Blocks.

Ну а про распараллеливание между компами это да… Хотя знаете, иногда нужно быстро проверить идею. Ключевое слово «быстро». В этих случаях удобно это написать на .NET (например), а затем переносить на С++. Хотя, конечно, такой сценарий больше подходит для исследователей-одиночек, чем для компаний.
А Вы голову включите, и постарайтесь понять, о чём написано. Если голова не работает, не читайте. Для здоровья полезнее.
Хм, а мы с Kroz поняли друг друга :)
Ну, началось… При чём тут OpenMP?

Мы обсуждаем что тут у нас на платформе в ближайшее время появится. Приходит сноб-знаток, и начинает нудеть. Много вы работающих приложений написали на базе OpenMP? Люди пользуются? Миллионы свои заработали?
Наверное я невнимательно читал доступную по Dryad информацию. Если у вас найдётся минутка, может быть вы сможете аргументированно указать на явные прорывы? Буду только рад.

P.S. OpenMP я противопоставляю новости в топике, о его особенностях я знаю. Хотя почему же, не так давно стало возможным применять его для автоматического распараллеливания и на системах с распределённой памятью.
Вот простая рабочая ситуация: есть вебовский проект на сишарпе, ему около трёх лет. Как там использовать OpenMP? Я не представляю. Мы используем внешние компоненты, писанные на C++, которые интегрируются с трудом — есть такая проблема. До сих пор, если нет исходников, единственный доступный способ интеграции C++ кода — это extern "C". Ну вот, с OpenMP, теоретически, можно попробовать компилировать его managed C++ компилятором и смотреть, как оно будет работать. Без гарантий.

Писать на PHP, Ruby? Они объективно медленнее. Писать на Java? Можно. Вопрос — есть ли решения, аналогичные PE для Java? Нет.

Каким образом сейчас достигается распараллеливание? Вручную. Есть такие объекты, про которые разработчик должен помнить — они расшарены и доступны с любой машины фермы. А про другие надо помнить, что они локальны. Это, как обычно, немного лишняя информация при разработке, но от неё никуда не деться.

Достоинства PE в том, что они позволяют в существующий проект внедрить параллельный код без особых проблем. Берётся, фактически, любое LINQ выражение в программе, и, при наличии нескольких ядер или процов, начинает обрабатываться параллельно. Без изучения тонкостей вопроса, без изучения нового языка программирования. И без геморроя с начальством, которое, как обычно, очень подозрительно. И с точки зрения разработчика это всё очень удобно. И из этого вовсе не следует, что сейчас разработчик не пишет многопоточные программы, просто сейчас это требуется делать вручную и держать в голове очень много лишней информации. Если хотите, могу привести пару интересных примеров.

Теперь про Dryad. Насколько я понимаю, Ваш вопрос таков: чем он лучше или круче MapReduce? Пока на Ваш вопрос ответ есть только теоретический. Собственно, то, что он также встраивается через LINQ в любой язык, которые поддерживается дотнетом, достоинством не является. По той простой причине, что я не сильно верю в возможности «автоматически» распараллеливать программу. Чтобы программа эффективно работала на сотне машин, её надо затачивать и надо разбираться. Пара-другая строчек Dryad LINQ её не спасёт.

Преимущество в том, что модель Dryad предлагает больше альтернатив к организации распределённых вычислений и MapReduce становится частным случаем. Это значит, что есть больше возможностей распараллеливать существующий код, а не писать его заново под парадигму MP. Хорошо это или плохо? Будет востребовано или нет? Сейчас ответить трудно. Но большая гибкость в Dryad заложена.
Мне сложно примерять на себя роль промышленного программиста на .NET, но я понял вас. Да, для .NET, и в частности для веб приложений это является сейчас трудностью. Для большинства программистов под .NET эта технология действительно будет очень полезна. Жаль, что она появилась позже аналога для Fortran/C/C++. Кстати говоря, о MPI для C# я слышал ещё год назад, сейчас это считают готовым продуктом.
Достоинства PE в том, что они позволяют в существующий проект внедрить параллельный код без особых проблем. Берётся, фактически, любое LINQ выражение в программе, и, при наличии нескольких ядер или процов, начинает обрабатываться параллельно. Без изучения тонкостей вопроса, без изучения нового языка программирования.
Что ещё раз доказывает, что можно сравнивать PE и OpenMP :) В удобстве OpenMP для своих прямых и не только задач я убедился.
Насколько я понимаю, Ваш вопрос таков: чем он лучше или круче MapReduce?
Нет, его я хотел сравнить с MPI. Имхо они одного порядка решения, а MapReduce действительно упрощённый вариант.

Просто жаль, что после того, как Microsoft не уделяла внимание HPC и более мирным параллельным технологиям, она начала выпускать продукты, как две капли воды воды похожие на давно известные решения :)
И из этого вовсе не следует, что сейчас разработчик не пишет многопоточные программы, просто сейчас это требуется делать вручную и держать в голове очень много лишней информации. Если хотите, могу привести пару интересных примеров.
Интересные примеры бесполезными никогда не будут. Не так часто удаётся прорваться и пообщаться с знающими людьми. Не сочтите снова за занудство, но только совсем простые примеры мне будут понятны, ибо мне приходится работать и на СКИФе, так что я немного в теме :)
Они действительно простые, эти примеры. Но оказались очень поучительными для меня в своё время. Взять такой простой паттерн, как singleton. Предположим, есть многопоточная программа, разные потоки в которой должны пользоваться одним и тем же объектом. Возникает вопрос — как его создавать? В однопоточной программе он создаётся по запросу:

Singleton *getSingleton()
{
  static *singleton = NULL;
  if(singleton == NULL)
    singleton = new Singleton();
  return singleton;
}


В многопоточной программе этот код может работать со сбоями. Например, первый поток проверяет singleton, он равен NULL, и поток создаёт объект. Но за это время второй поток успевает создать объект раньше и присвоить значение переменной signleton.

Может так оказаться, что в программе оказываются два одиночки. Очевидно, нужно как то регламентировать создание объекта. В Windows API это делается, например, через критические секции (critical sections). Собственно, это упрощённый вариант блокировки, когда несклько потоков пытаются обратиться к одному и тому же объекту.

Возникает вопрос: когда должна начинаться и когда заканчиваться блокировка? Оказывается, правильный вариант таков:

Singleton *getSingleton()
{
  static *singleton = NULL;
  if(singleton == NULL)
  {
    Lock();
    if(singleton == NULL)
      singleton = new Singleton();
    Unlock();
  }
  return singleton;
}


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

> Нет, его я хотел сравнить с MPI. Имхо они одного порядка решения, а MapReduce
> действительно упрощённый вариант.

Не знаю. Там ведь фишка не только в архитектурном решении, там фишка в LINQ. Нормально параллелятся функциональные языки, и LINQ как раз такой подъязык. Подозреваю, что код на Си++ окажется просто сложнее, поскольку там вся функциональность в шаблонах.

Ну вот, например:

DryadDataContext ddc = new DryadDataContext(dir);
DryadTable<LineRecord> table = ddc.GetTable<LineRecord>(filename);
IQueryable<string> lines = table.Select(lr => lr.line);
IQueryable<string> match = search(lines, searchString);

...

public static IQueryable<string>
search(IQueryable<string> collection,
string searchString)
{
return collection.Where(s => s.IndexOf(searchString) >= 0);
}


Всё, что идёт до вызова table.Select(lr => lr.line) — ввод данных, который на текстовых файлах не параллелится (хотя есть варианты). А вот вызов search уже может выполняться на разных машинах. Главное же то, что не надо писать новую программу для всего этого, нужно добавить три строчки, а всё остальное уже именно так и пишется в C#.

> Просто жаль, что после того, как Microsoft не уделяла внимание HPC и более мирным
> параллельным технологиям, она начала выпускать продукты, как две капли воды воды
> похожие на давно известные решения :)

Почему не уделяла? Им с задачей распараллеливания приходится работать ничуть не меньше, чем гуглу. Из 10-та самых посещаемых сайтов в мире, три или четыре принадлежат Microsoft. Просто сейчас есть почва для промышленных решений — есть сообщество программистов, которые пишут на C#, есть проекты, есть LINQ. Просто всё это не так быстро делается, но делается.
LINQ полезная вещь, судя по тому что про неё попадается на глаза. Но если говорить об автоматическом распараллеливании, то Intel уже выпустила Cluster OpenMP, работающую на распределённых системах.

Не знаю. Там ведь фишка не только в архитектурном решении, там фишка в LINQ. Нормально параллелятся функциональные языки, и LINQ как раз такой подъязык. Подозреваю, что код на Си++ окажется просто сложнее, поскольку там вся функциональность в шаблонах.
Если параллелить по задачам, то думаю и нынешних средств хватит, всё-таки все примеры выше и в статье так или иначе относятся к распараллеливанию циклической обработки данных. Для этого в C(++) ничто не мешает особо :)

К сожалению мой интерес в области параллельного программирования не очень далеко распространяется, так что рассуждать о практической полезности создавать настолько автоматизированные средства мне сложно. Главное чтобы программисты не забывали о появляющихся при использовании этих средств последствиях, которые они не смогут скорее всего контролировать в таком случае.
> Для этого в C(++) ничто не мешает особо :)

О, это тема для отдельного холивора. :) Тут можно было бы привести пример с тем самым map-reduce. Само название пошло от двух функций: map (отображение) и reduce (свёртка), которые очень часто применяются в ФП.

Если взять, например, вычисление синуса: sin(x) = x — x^3/3! + x^5/5! ..., то в императивном стиле функция будет выглядеть так:

double sin(double x)
{
  int iteration = 3;
  int sign = -1;
  double factorial = 6;

  double result = x;
  double pow = x * x * x;

  do
  {
    double next = (sign * pow)/factorial;
    result += next;
    sign = -sign;
    pow *= x * x;
    iteration += 2;
    factorial * iteration * (iteration - 1);
  }
  while(iteration <= 11);

  return result;
}


И её довольно трудно параллелить, по крайней мере автоматически. (Неизбежный комментарий: на 11-й итерации мы достигаем наибольшей для double точности в 13 или 14 цифр после запятой). В функциональном стиле она будет уже другой.

let sin_mmbr x i = (x^i * (-1)^((i - 1)/2))/factorial(i)
let after_map x = map (sin_mmbr x) [1..3..11]
let sin x = fold_left (+) 0 (after_map x)


Оба кода писал на ходу, поэтому возможны ошибки и там, и там. Во втором случае главное отличие в том, что здесь не задан порядок вычислений. Есть некий список чисел от 1 до 11 с шагом 2. К каждому числу нужно применить преобразование sin_mmbr. Это map. На этом этапе возможно естественное распараллеливание. Вторая часть — reduce, свести результаты воедино. И эта операция тоже распаралеливается (может, по крайней мере). В данном случае свёртку выполняет функция fold_left.
:) Одно дело разная запись, другое — не согласуемые концепции языков. Как я уже сказал, второго я особо не вижу в параллелизации C++. Что касается [1..3..11], то это уже синтаксический сахар, который, в общем-то можно использовать и в императивных языках, если написать нужный препроцессор. А если использовать тот же OpenMP, то эту функцию можно записать и на C++ с возможностью распараллеливания.

Холивар я вижу лишь в том, что вы, как и многие приводящие этот и похожие примеры, сознательно сократили вычисления синуса в функциональном стиле, не учтя оптимизацию вычисления факториала в примере на C++ и сократив количество кода чисто языковыми конструкциями, которые можно ввести в любом языке. При идентичной сути эти фрагменты будут не так сильно отличаться, а распараллеливать можно и C++ код, для этого не нужно функциональное программирование :)
Здесь дело не в синтаксическом сахаре. [1..3..11] это действительно ерунда. Основное достоинство ФП — в данном случае и map и reduce уже выполняются параллельно. То есть, это не теоретическая возможность, существующие системы уже так работают.

И основное отличие в том, что (если, например, мы хотим составить таблицу синусов до миллионного знака после запятой), код на Си++ нужно будет распараллеливать вручную. А код на OCaml нет. Вот он такой, какой есть, и останется.

Здесь речь не о краткости кода (в Си++ вычисление факториала можно было бы вынести в отдельную функцию, но тут уж тяга к правде сыграла — так не пишут). Только о возможности автоматического распараллеливания.
Я в конечном счёте считаю, что наличие для распараллеливания отдельной строчки #pragma omp parallel или .AsParallel() в LINQ не такая уж и сложность для пишущего программу :) Тем более, что компиляторы, поддерживающие OpenMP, обычно имеют опции для выявления конструкций, поддающихся распараллеливанию. Так что это тоже не теория, а вполне себе практика :)

Очень рад за .NET-чиков, что теперь и им это доступно. Надеюсь, что .AsParallel будет реализован во всех необходимых местах и костылей придётся писать меньше.
Вот только непонятные «эти» программисты. Мы тут с вами довольно на интересную тему беседуем, а они уже забыли про новость :)
Программисты занимаются внедрением. А на Си я к сожалению практически не писал и слова MapReduce и OpenMP мне мало о чем говорят. Но я с удовольствием читаю и делаю заметки по разбору на будущее.
Кстати, в PE есть недоработки. На то и CTP. PE в некоторых случаях (например у нас на дуал-ксеоне) при отсутствии работы начинает ее активно искать. При этом так активно, что занимает 80% от всех 8 ядер.
Мне вчера попался интересный доклад на эту тему: channel9.msdn.com/pdc2008/TL25/. Аудитория там правда C++ программисты и для них Microsoft поддерживает OpenMP и MPI в оригинальном виде, однако в докладе много есть и про их специфичные инструменты, которые делаются сейчас для всех .NET языков. Если вас интересует, то в Википедии вполне достойно представлены эти технологии.
PE в некоторых случаях (например у нас на дуал-ксеоне) при отсутствии работы начинает ее активно искать. При этом так активно, что занимает 80% от всех 8 ядер.
Лишнее подтверждение тому, что от всех проблем эти абстракции не спасут. конечно же, они скорее всего исправят шедулер потоков, если дело в нём, но программист по хорошему тоже должен думать о том, чтобы все потоки выполнялись примерно одинаковое время. В конечном счёте это выгоднее :)
Это известный им баг.

Т.е. если просто запусть процесс веб-сервиса, отрезанный от мира, то он начинает в холостую гонять комп сразу после загрузки библиотеки. Хотя никаких операций с ней не производилось. На девелопмент-сервере такого эффекта нет.
Тут всё-таки есть одна тонкость. Сам пример показывает, что для ФЯ map и reduce не являются чем-то искусственным. Наоборот, они из ФП как раз и пришли. И параллелятся они прекрасно сами по себе, ну вот разве с reduce бывают сложности.

А вот как будет распараллелен приведённый код на Си++, я не знаю. Думаю, будут серьёзные сложности, если речь идёт об автоматическом распараллеливании. Вручную, конечно, без проблем.

Про доступность есть две точки зрения. С одной стороны, всё это уже можно крутить в личных проектах на свой страх и риск. Там много интересных наработок, например, DLR (поддержка динамических языков) и F# (язык на базе OCaml, где параллельность уже по умолчанию должна работать). Но на работе на боевой сервер не дадут PE поставить, пока не выйдет официальный .NET 4. :)

Поэтому с одной стороны всё уже есть, а с другой — ждём. :)
Но ведь можно было написать и на функциональном языке этот пример с использованием цикла? А значит об использовании в данном месте map/reduce ему нужно отдельно думать, по крайней мере он должен был это где изучить/услышать/прочитать :) Особенно если его первым языком был какой-то из «последовательных». Так что в этом смысле нет разницы в том, «думает» ли программист при проектировании расчёта на языке map/reduce(а ведь не всё можно к нему свести), или думает по привычной ему схеме, пишет циклы и потом(либо по ходу действия) расставлять в коде комментарии OpenMP.

P.S. Посмотрю завтра, будет ли Intel Compiler предлагать распараллеливание цикла в вашем примере :)
Ну, как бы, теоретически, изучение ФП как раз и предполагает осваивание таких вот подходов к решению. Я бы, например, рекомендовал разработчикам без опыта, решать любую такую вычислительную задачу с помощью Excel, тогда опыт быстро наработается. :)
Если человек научится, он сможет написать это и не на функциональном языке, это я и хотел сказать :) Благо средства есть.
Трудно спорить. Но мой опыт (небольшой, кстати) разработки таких вот штук на Си++ привёл меня к неутешительным выводам.

Да, библиотеку нечёткой логики для Си++ разработать можно.

Нет, человеческим этот код назвать никак нельзя. :)

То же самое относится не только к Си++, но и к Java, и в очень большой мере к C#. В последнем, хоть и есть функциональные расширения (лямбды с замыканиями, LINQ и даже каррирование в какой-то мере), многого всё-таки нет. Но всё это есть в F#, и через год мы сможем писать параллельный код, практически, одной левой. :)
Поживём — увидим :) Может быть даже жоведу себя до проведения тестов производительности, когда будет что сравнивать. Для меня это важнее, чем небольшое удобство при разработке :)
Гарантирую: будет страшно! Помните время, когда Java завоёвывала себе место под солнцем? Виртуальная машина, сборка мусора — и лозунг: «всё-таки мы не намного медленнее Си++, всего на каких-то 30%».

Прошло 10 лет, ребята поработали над оптимизацией, над сборщиком, над JIT, и вот уже тесты показывают странную вещь: код на Java быстрее кода на Си++. Одна проблема осталась: старт приложений всё-таки небыстрый. Сейчас решают.

Сделано настолько хорошо, что .NET всё ещё отстаёт по сборщику мусора.

Подозреваю, с ФЯ будет то же самое. Через год F# будет в продакшене, можно будет сравнивать. Но и сейчас есть первые ласточки, очень странные. Есть такой архиватор freearc того же класса, что и 7zip. Где-то полгода назад он стал первым по скорости среди архиваторов этого типа. 7zip написан на C++ и C, а freearc на Haskell и C. Вот такая удивительная штука. :)
Присоединился. :)

Думаю, в ближайшие 10 лет нас ждут серьёзные прорывы, потому что параллельное программирование стало востребованным — многоядерные процессоры практически на каждом рабочем столе.

Лет 5 назад серьёзно этим занимались только разработчики серверного софта и научные сообщества. А теперь придётся заниматься всем. :) Так что я стараюсь не отставать, и мало помалу изучаю наработки.
… вводным обзором в Parallel Extendions.
подправьте «Extendions»… Правда полезная статья =)
Исправил. Спасибо :)
Огромное спасибо за столь полезную статью, как раз сейчас с этим сталкиваюсь, когда происходит длительная обработка данных, и при этом процессор загружен максимум на 30-40%, думаю теперь временные затраты на обработку уменьшатся вдвое, если не больше.
UFO just landed and posted this here
Лучше, наверное, чтобы каждое распараллеливалось: тогда при низком количестве обращений использование процессоров будет выше. Parralels должна сама следить за распределением нагрузки на процессоры.

Но проще проверить запустив тест какой-нибудь. :)
где-то читал пример из жизни, когда на сервере подняли несколько виртуальных машин вместо того, чтобы нагружать один многоядерный процессор несколькими задачами, они нагрузили каждую машину своей, выигрыш был ощутимый

виртуализация — это тоже вариант
Говорят, в 2008-м сервере это уже не так актуально. Программисты Микрософта таки переписали sheduler потоков, так что теперь они привязываются к своим процессорам. А раньше потоки после простоя могли продолжить выполнение на другом ядре, в результате чего были накладки на переключение и перезапись кешей. Двигаются в правильном направлении :)
Вообще такой подход как вы описали — довольно таки сомнительный. Есть поток 1, он запустился на одном процессоре, запустился поток 2 и полностью загрузил процессор. Теперь если запрос к потоку 1 опять придет, то он будет вынужден выполняться медленно, так как уже привязан к этому процессору. А у вас там ещё 7 простаивают…

Если брать на примере IIS6, то там потоки «старались» выполняться на тех же процессорах, но это было не гарантированно. Гарантированно запрос выполнялся именно на свободном процессоре.
Ко мне эта новость пришла из других рук. Но вы верно уточнили, «старались». Так вот если раньше этим нельзя было управлять, то в 2008-м такая возможность вроде как появилась. Просто если параллельно выполняются несколько вычислительных процессов на разных ядрах и известно, что нагрузку они создают одинаковую, то их лучше привязать намертво к процессорам. А раньше были частые случаи, когда при синхронизациях, и следовательно простоях, потоки перемещались между ядрами, что естественно приводило к падению производительности. А для серверов, работающих по потоковой схеме, это не должно быть так критично.
Мне кажется, лучше настроить на обработку первым свободным процессом, как в IIS 6. Так же если страница выполяет что-то тяжелое и сервер нагружен пользователями, то лучше эти операции делать при помощи асинхронных вычислений, чтобы не занимать поток на длительное время.

PS. Сам в IIS7 этим не сталкивался… он позволяет распараллеливать каждое обращение на все процессоры?
Можно, например, увеличить у ApplicationPool'а количество Working Process. Тогда они будут занимать разные процессоры.
Конечно, это и получится то что я написал «настроить на обработку первым свободным процессом».

Но так чтобы сам запрос параллелился — не думаю. Разве что использовать PE для расчетов, но это к IIS отношения не имеет.

Я просто не знаю именно такой фичи как прозвучала в вопросе «чтобы каждое обращение распараллеливалось на все процессоры», чтобы это можно было организовать средствами IIS.
Понял. Такой я тоже не знаю. Видимо под распараллеливанием и понимались PE.
А что это за зубная паста на картинке :)?
По мотивам Aquafresh нарисовал. :)
Параллельная обработка зубов.
теперь даже при чистке зубов, буду вспоминать тему параллельности.
У вас неэффективный алгоритм проверки числа на простоту, т.к. нужно проверять до sqrt(b) а не до n/2. Боюсь что неэффективный алгоритм никакие Parallel Extensions не спасут =)
Данный алгоритм здесь исключительно для того, чтобы было чем занять процессор и не претендует на эффективность. Даже с квадратным корнем он никуда не годится :)
Надо учитывать что по лицензии (насколько я её понимаю) PFX нельзя использовать в готовых продуктах, только для тестирования.
С другой стороны, Mono сделали свою версию — и в ней такого ограничения нет (но у меня не собралось).
Спасибо за статью!
Кстати, цикл с простыми числами можно сократить до корня, и проверять хотя бы с шагом два (отбросив четные). А можно и еще быстреее :)
Меня терзают смутные сомнения. Вообще то задача управления потоков и разруливания принципов распределения ресурсов между процессорами — задача достаточно низкоуровнего характера. Т.е. по хорошему сама среда, в которой выполняется приложение пользователя должна заниматься этими делами, предоставляя возможность программисту бизнес приложений сконцентрироваться на бизнес-задачах соответственно. А здесь вместо этого мы имеем coupling с resource management и самому разработчику предлагается а) знать, на каких машинах будет выполняться приложение, б) вставлять в код приложения подобного рода затычки, если есть вероятность, что приложение установят на многопроцессорную машину. в) менеджить это все добро со всеми вытекающими последствиями.
Вопрос — действительно ли стоит так восторгаться сим замечательным поделием? Может это просто hot-fix от микрософт перед выпуском фреймворка, который будет работать нормально на многопроцессорных системах?
Да, впринципе может быть еще какой-нибудь подтип приложений, в которых нужно руками распределять нагрузку на процессоры, и там такой подход будет несомненно полезен. Но повальное большинство проектов к такому классу не относятся.
Фреймворк и так работает нормально на многопроцессорных системах, и работал с первой версии. Просто тогда всё приходилось делать вручную через Sytesm.Threading.Thread.

Собственно, единственное, что реально можно сделать для автоматического распараллеливания — пересаживать народ на функциональные языки. Ну вот, с одной стороны MS готовит F#, с другой — сделала LINQ, который сам по себе является функциональным подъязыком.

Ну и непонятно, почему Вы пишете, что программисту надо знать, на каких машинах будет выполняться программа. Использовать надо везде. Если машина будет многоядерной, ядра подхватятся. Если одноядерной, накладные расходы будут небольшими. В существующий код больших изменений вносить не придётся — это самый большой плюс.
круть, наконец-то, Extensions — отличная штука :)
Насколько я знаю он войдёт в .Net 4.0, так что это действительно перспективная вещь.
Действительно крутая и удобная штука. Возьму на заметку, спасибо ;)
Sign up to leave a comment.

Articles