Подтвердить что ты не робот

Какую модель параллельного программирования вы рекомендуете сегодня, чтобы воспользоваться преимуществами многоядерных процессоров завтра?

Если вы пишете новое приложение с нуля сегодня и хотите, чтобы он масштабировался ко всем ядрам, которые вы могли бы добавить на него завтра, какую параллельную модель программирования/систему/язык/библиотеку вы бы выбрали? Почему?

Меня особенно интересуют ответы по этим осям:

  • Производительность программы/простота использования (могут ли смертные ее успешно использовать?)
  • Целевой домен приложения (какие проблемы у него (не) хорошо?)
  • Concurrency стиль (поддерживает ли он задачи, конвейеры, данные parallelism, сообщения...?)
  • Поддержание работоспособности/будущая проверка (будет ли кто-нибудь еще использовать ее через 20 лет?)
  • Производительность (как она масштабируется на каком оборудовании?)

Я сознательно расплывчато отношусь к природе приложения в ожидании получения хороших общих ответов, полезных для различных приложений.

4b9b3361

Ответ 1

Для многоядерного программирования может потребоваться более одной парадигмы. Некоторые текущие соперники:

  • MapReduce. Это хорошо работает, когда проблему можно легко разложить на параллельные куски.
  • Вложенные данные Parallelism. Это похоже на MapReduce, но на самом деле поддерживает рекурсивную декомпозицию проблемы, даже если рекурсивные куски имеют неправильный размер. Ищите NDP, чтобы быть большой победой в чисто функциональных языках, работающих на массовом параллельном, но ограниченном оборудовании (например, на графических процессорах).
  • Программная транзакционная память. Если вам нужны традиционные потоки, STM делает их терпимыми. Вы платите 50% производительности в критических разделах, но вы можете масштабировать сложные схемы блокировки до 100 процессоров без боли. Однако это не будет работать для распределенных систем.
  • Параллельные потоки объектов с обменом сообщениями. Эта действительно умная модель используется Эрланг. Каждый "объект" становится легким потоком, а объекты общаются посредством асинхронных сообщений и сопоставления шаблонов. Это в основном истинное параллельное OO. Это успешно преуспело в нескольких приложениях реального мира, и оно отлично работает для ненадежных распределенных систем.

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

Ответ 2

Два решения, которые мне очень нравятся, объединить калькуляцию (JoCaml, Polyphonic С#, ) и модель актера (Erlang, Scala, E, Io).

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

  • Люди понимают транзакции в базах данных
  • Уже есть разговоры об аппаратном обеспечении оперативной памяти.
  • Насколько нам всем хотелось бы, нити, вероятно, будут доминирующей моделью concurrency в течение следующих нескольких десятилетий, как это ни печально. STM может значительно уменьшить боль.

Ответ 3

Парадигма mapreduce/hadoop полезна и актуальна. Специально для людей, которые привыкли к языкам, таким как perl, идея сопоставления массива и выполнения некоторых действий над каждым элементом должна происходить довольно плавно и естественно, и mapreduce/hadoop просто переходит к следующему этапу и говорит, что нет причин, по которым каждый элемент массива должен обрабатываться на одном компьютере.

В некотором смысле это больше проверено на битву, поскольку Google использует mapreduce, и многие люди используют hadoop и показали, что он хорошо работает для масштабирования приложений на нескольких компьютерах по сети. И если вы можете масштабировать несколько компьютеров по сети, вы можете масштабировать несколько ядер в одной машине.

Ответ 4

Для приложения .NET я выбираю ".NET Parallel Extensions (PLINQ)" он чрезвычайно прост в использовании и позволяет мне распараллелить существующий код в минутах.

  • Это просто, чтобы узнать
  • Используется для выполнения сложных операций над большими массивами объектов, поэтому я не могу комментировать другие приложения
  • Поддержка задач и каналов связи
  • Должен поддерживаться в течение следующих нескольких лет, но кто знает наверняка?
  • Версия CTP имеет некоторые проблемы с производительностью, но уже выглядит очень многообещающей.

Моно скорее всего, получит поддержку PLINQ, поэтому это может быть и кросс-платформенное решение.

Ответ 5

Для тяжелых вычислений и т.п. чисто функциональные языки, такие как Haskell, легко parallelizable без каких-либо усилий со стороны программиста. Помимо обучения Haskell, то есть.

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

Ответ 6

kamaelia - это инфраструктура python для создания приложений с большим количеством коммуникационных процессов.

http://www.kamaelia.org/cat-trans-medium.png Kamaelia - Concurrency полезен, веселый

В Kamaelia вы создаете системы из простых компонентов, которые разговаривают друг с другом. Это ускоряет разработку, значительно облегчает техническое обслуживание, а также означает, что вы создаете естественное параллельное программное обеспечение. Он предназначен для доступа к любому разработчику, включая новичков. Это также делает его забавным:)

Какие системы? Сетевые серверы, клиенты, настольные приложения, игры на основе Pygame, транскодированные системы и конвейеры, системы цифрового телевидения, уничтожители спама, учебные инструменты и многое другое:)

См. также вопрос Многоядерный и Concurrency - Языки, библиотеки и методы разработки

Ответ 7

Я делаю ставку на передачу контуров событий с помощью promises, как это реализовано в таких системах, как Twisted, E, AmbientTalk и другие. Они сохраняют возможность писать код с такими же предположениями модели исполнения, что и неконкурентные/параллельные приложения, но масштабируются для распределенных и параллельных систем. (Вот почему я работаю над Ecru.)

Ответ 8

Проверьте Erlang. Google для этого, и смотреть различные презентации и видео. Многие из программистов и архитекторов, которых я уважаю, вполне восприимчивы к его масштабируемости. Мы используем его там, где я очень сильно работаю...

Ответ 9

Как уже упоминалось, чисто функциональные языки по своей сути параллельны. Тем не менее, императивные языки гораздо более интуитивны для многих людей, и мы глубоко укоренились в императивном кодексе. Основная проблема заключается в том, что чистые функциональные языки явно выражают побочные эффекты, а побочные эффекты выражаются неявно в императивных языках по порядку утверждений.

Я считаю, что методы декларативного выражения побочных эффектов (например, в объектно-ориентированной структуре) позволят компиляторам разлагать императивные утверждения в их функциональные отношения. Затем это должно позволить автоматически распараллеливать код так же, как и чистый функциональный код.

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

Ответ 10

Я удивлен, что никто не предложил MPI (интерфейс передачи сообщений). Было показано, что, рассчитанные на распределенную память, программы MPI с существенной и частой глобальной связью (решения линейных и нелинейных уравнений с миллиардами неизвестных) имеют масштаб до 200 кГц.

Ответ 11

Параметр Qt предлагает реализацию MapReduce для многоядерных процессоров, которая очень проста в использовании. Это multiOS.

Ответ 12

Если ваш проблемный домен позволяет подумать о том, что ни одна модель не имеет ничего общего. Чем меньше вы делитесь между процессами и потоками, тем меньше вам приходится проектировать сложные модели concurrency.

Ответ 14

Этот вопрос, похоже, продолжает появляться в разных формулировках - возможно, в StackOverflow есть разные группы. Flow-Based Programming (FBP) - это концепция/методология, которая существует уже более 30 лет и используется для обработки большей части пакетная обработка в крупном канадском банке. Он имеет потоковые реализации в Java и С#, хотя более ранние реализации были основаны на волокнах (С++ и mainframe Assembler - тот, который используется в банке). Большинство подходов к проблеме использования многоядерности включают попытку взять обычную однопоточную программу и выяснить, какие части могут работать параллельно. FBP использует другой подход: приложение разработано с самого начала в терминах нескольких компонентов "черного ящика", работающих асинхронно (подумайте о сборочной линии производства). Поскольку интерфейс между компонентами является потоком данных, FBP по существу не зависит от языка и поэтому поддерживает приложения на смешанном языке и языки, специфичные для домена. По той же причине побочные эффекты сведены к минимуму. Его также можно охарактеризовать как модель "ничего общего" и MOM (ориентированное на сообщения промежуточное ПО). MapReduce, по-видимому, является особым случаем FBP. FBP отличается от Erlang главным образом тем, что Erlang работает с точки зрения многих короткоживущих потоков, поэтому зеленые потоки здесь более уместны, тогда как FBP использует меньше (обычно от нескольких десятков до нескольких сотен) более длинных потоков. Для части пакетной сети, которая была в повседневной эксплуатации более 30 лет, см. часть пакетной сети. Для высокоуровневого дизайна интерактивного приложения см. Брокерское приложение высокого уровня дизайна. Было обнаружено, что FBP приводит к значительно большему числу поддерживаемых приложений, а также к улучшенным истекшим временам - даже на одноядерных машинах!

Ответ 15

Задача очереди с несколькими рабочими системами (не уверены в правильности терминологии - очередь сообщений?)

Почему?

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

Кроме того, в отличие от причин, скажем, Haskell или Erlang настолько параллельны/параллелизуемы (?), это полностью языковой агностик - вы можете тривиально реализовать такую ​​систему на C, Python или на любом другом языке (даже используя shell scripting), в то время как я сомневаюсь, что bash в ближайшее время получит транзакционную память программного обеспечения или объединение-исчисление.

Ответ 16

Мы использовали PARLANSE, параллельное программирование langauge с явной спецификацией частичного порядка concurrency за последнее десятилетие, для реализации масштабируемой системы анализа и преобразования программ (DMS Software Reengineering Toolkit), которая в основном выполняет символические, а не числовые вычисления. PARLANSE - это скомпилированный C-подобный язык с традиционными типами скалярных типов данных, целыми числами, типами float, динамическими типами данных и массивом, составными структурами данных и объединением и функциями с лексическим диапазоном. Хотя большинство языков - ваниль (арифметические выражения над операндами, операторы if-then-else, делают циклы, вызовы функций), parallelism - нет. parallelism выражается путем определения отношения "предшествует" над блоками кода (например, a до b, a до c, d до c) написанный как

(|;  a  (... a computation)
     (<< a) b ( ... b computation ... )
     (<< a) c ( ....c computation ...)
     (>> c) d ( ... d computation...)
)|;

где < и → операторы ссылаются на "порядок во времени". Компилятор PARLANSE может видеть эти параллельные вычисления и предопределять все структуры, необходимые для вычисления зерна a, b, c, d и генерировать собственный код для запуска/остановки каждого, что минимизирует накладные расходы для запуска и остановки этих параллельных зерен.

Посмотрите эту ссылку для параллельного итеративного углубления поиска оптимальных решений для 15-головоломки, который является 4x4 старшим братом 8-головоломки. Он использует только параллельный потенциал как конструктор parallelism (|| abcd), который говорит, что нет никаких ограничений частичного порядка вычислений abcd, но он также использует спекуляцию и асинхронно прерывает задачи, которые не найдут решения. Его много идей в довольно маленьком коде.

PARLANSE работает на многоядерных ПК. Большая программа PARLANSE (мы построили много с 1 миллионом + строк и более) будет иметь тысячи этих частичных заказов, некоторые из которых вызовут функции, которые содержат другие. До сих пор у нас были хорошие результаты с 8 процессорами и скромная прибыль до 16, и мы все еще настраиваем систему. (Мы считаем, что реальная проблема с большим количеством ядер на текущих ПК - это пропускная способность памяти: 16 ядер, подрывающих подсистему памяти, создает огромную потребность в пропускной способности).

Большинство других языков не выставляют parallelism, поэтому их трудно найти, а системы времени выполнения платят высокую цену за планирование вычислений зерен с использованием примитивов общего назначения. Мы считаем, что рецепт катастрофы или, по крайней мере, плохой работы из-за закона Амхдала: если количество машинных инструкций для планирования зерна велико по сравнению с работой, вы не можете быть эффективными. OTOH, если вы настаиваете на вычислении зерен со многими машинными инструкциями, чтобы затраты на планирование были относительно низкими, вы не можете найти вычислительные зерна, которые являются независимыми, и поэтому у вас нет полезного parallelism для планирования. Поэтому ключевая идея PARLANSE заключается в том, чтобы минимизировать затраты на планирование зерен, чтобы зерна могли быть небольшими, чтобы их можно было найти в реальном коде. Понимание этого компромисса было вызвано неудачной неудачей парадигмы чистого потока данных, которая делала все параллельно с крошечными параллельными кусками (например, оператор добавления).

Мы работаем над этим в течение десятилетия. Это трудно понять. Я не вижу, как люди, которые не строили параллельные langauges и используют/настраивают их для этого временного интервала, имеют серьезные шансы создать эффективные параллельные системы.

Ответ 17

Мне очень нравится модель Clojure. Clojure использует комбинацию неизменных структур данных и транзакционной памяти программного обеспечения.

Неизменяемые структуры данных - это те, которые никогда не меняются. Новые версии структур могут быть созданы с измененными данными, но если у вас есть "указатель" на структуру данных, он никогда не изменится из-под вас. Это хорошо, потому что вы можете получить доступ к этим данным, не беспокоясь о проблемах concurrency.

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

Существует видео от автора Rich Hickey, который идет намного подробнее.

Ответ 18

Полезным путем может быть OpenCL, который предоставляет средства для распределения определенных видов вычислительных нагрузок по гетерогенным вычислительным ресурсам, IE тот же код будет работать на многоядерном процессоре, а также на товарных графических процессорах. Недавно ATI выпустила именно такую ​​toolchain. NVidia CUDA toolchain похож, хотя и несколько более ограниченный. Также представляется, что Nvidia имеет OpenCL sdk в работах

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

Ответ 19

Если вы сегодня пишете новое приложение с нуля, и хотите, чтобы он масштабировался во все ядра, которые вы могли бы на него завтра добавить, какую параллельную модель программирования/систему/язык/библиотеку вы бы выбрали?

Возможно, наиболее широко применимым сегодня является очередь задач в стиле Cilk (теперь доступна в .NET 4). Они отлично подходят для проблем, которые могут быть решены с помощью деления и покорения с предсказуемой сложностью для подзадач (таких как параллельные map и reduce над массивами, где известна сложность аргументов функции, а также алгоритмы, такие как quicksort), и которая охватывает многие реальные проблемы.

Кроме того, это относится только к архитектурам с общей памятью, таким как сегодня многоядерные процессоры. Хотя я не верю, что эта базовая архитектура исчезнет в ближайшее время, я верю, что в какой-то момент она должна быть объединена с распределенным parallelism. Это будет либо в виде кластера многоядерных процессоров на многоядерном процессоре с сообщением, проходящим между мультикодами, либо в виде иерархии ядер с предсказуемым временем связи между ними. Для достижения максимальной эффективности потребуются существенно разные модели программирования, и я не думаю, что о них известно много.

Ответ 20

Существует три части параллельного программирования IMO: идентифицируйте parallelism и укажите parallelism. Идентифицировать = Разбить алгоритм на параллельные куски работы, указать = выполнение фактического кодирования/отладки. Идентифицировать не зависит от того, какую структуру вы будете использовать, чтобы указать parallelism, и я не думаю, что структура может там помочь. Он имеет хорошее понимание вашего приложения, целевой платформы, общих параллельных программных компромиссов (аппаратных латентностей и т.д.), А главное - опыта. Укажите, однако, можно обсудить, и вот что я пытаюсь ответить ниже:

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

Pthreads (его нет в действительности, но определенно применимо):

Pro: -Pthreads чрезвычайно общий. Для меня pthreads похожи на сборку параллельного программирования. Вы можете закодировать любую парадигму в pthreads. - Он гибкий, поэтому вы можете сделать его настолько высокой, насколько хотите. Нет никаких неотъемлемых ограничений, чтобы замедлить вас. Вы можете написать свои собственные конструкции и примитивы и получить как можно больше скорости.

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

OpenMP:

Плюсы: - Кодекс выглядит чистым, водопровод и разделение задач - в основном под капотом -Semi гибкий. Это дает вам несколько интересных возможностей для планирования работы

Против: -Meant для простой петли, такой как parallelism. (Новейший Intel verion также поддерживает задачи, но задачи такие же, как и Cilk). - Другие структуры могут быть или не быть хорошо написаны для выполнения. Реализация GNU - это нормально. Intel ICC работал лучше для меня, но я бы скорее написал некоторые вещи для повышения производительности.

Cilk, Intel TBB, Apple GCD:

Плюсы: -Положительно оптимальные базовые алгоритмы для уровня задач parallelism -Специальное управление последовательными/параллельными задачами -TBB также имеет конвейерную инфраструктуру parallelism, которую я использовал (это не лучшее, чтобы быть откровенным) -Устанавливает задачу написания большого количества кода для систем на основе задач, которые могут быть большим плюсом, если вы коротко

Против: -Уменьшенный контроль производительности базовых структур. Я знаю, что Intel TBB имеет очень плохо выполняющие базовые структуры данных, например, рабочая очередь была плохой (в 2008 году, когда я ее увидел). -Код выглядит ужасно иногда со всеми ключевыми словами и ключевыми словами, которые они хотят использовать -Подробнее читает множество ссылок, чтобы понять их "гибкие" API.

Ответ 21

Я бы использовал Java - его портативный, поэтому будущие процессоры не будут проблемой. Я бы также закодировал свое приложение со слоями, разделяющими интерфейс/логику и данные (более похожее на веб-приложение уровня 3 уровня) со стандартными подпрограммами mutex в качестве библиотеки (меньше отладки параллельного кода). Помните, что веб-серверы очень хорошо масштабируются для многих процессоров и являются наименее болезненным путем для многоядерных процессоров. Либо это, либо посмотрите на старую модель Connection Machine с виртуальным процессором, привязанным к данным.

Ответ 22

Erlang - это более "зрелое решение" и является портативным и открытым исходным кодом. Я работал с Polyphonic С#, я не знаю, как было бы программировать каждый день в нем.

Существуют библиотеки и расширения для почти каждого языка/ОС под солнцем, транзакционная память Google. Это интересный подход от MS.