Функциональное программирование и многоядерная архитектура - PullRequest
16 голосов
/ 08 октября 2008

Я где-то читал, что функциональное программирование подходит для использования преимуществ многоядерных вычислений. Я действительно не понял идею. Это связано с лямбда-исчислением и архитектурой фон Неймана?

Ответы [ 9 ]

12 голосов
/ 08 октября 2008

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

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

Другое преимущество заключается в том, что некоторые процессы, которые очень легко распараллеливаются, например, итерации, абстрагируются от функций. В C ++ у вас может быть цикл for, который запускает некоторую обработку данных для каждого элемента в списке. Но у компилятора нет возможности узнать, могут ли эти операции безопасно выполняться параллельно - возможно, результат одного зависит от предыдущего. Когда используется такая функция, как map() или reduce(), компилятор может знать, что между вызовами нет зависимости. Таким образом, можно обрабатывать несколько предметов одновременно.

12 голосов
/ 08 октября 2008

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

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

9 голосов
/ 28 июня 2010

Я где-то читал, что функциональное программирование подходит для использования преимуществ многоядерных вычислений ... Я не совсем понял эту идею. Это связано с лямбда-исчислением и архитектурой фон Неймана?

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

К сожалению, эта вера давно опровергнута по нескольким причинам:

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

  • Чисто функциональные структуры данных плохо масштабируются, потому что они нагружают общие ресурсы, включая распределитель / ГХ и полосу пропускания основной памяти. Таким образом, распараллеленные чисто функциональные программы часто получают низкое ускорение при увеличении количества ядер.

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

Например, ненастоящая двухстрочная быстрая сортировка , часто цитируемая сообществом Haskell, обычно работает в тысячи раз медленнее, чем реальная быстрая сортировка на месте, написанная на более традиционном языке, таком как F #. Более того, хотя вы можете легко распараллелить элегантную программу на Haskell, вы вряд ли увидите какое-либо улучшение производительности, поскольку все ненужное копирование делает одно ядро ​​насыщенным по всей полосе пропускания основной памяти многоядерной машины, делая параллелизм бесполезным. На самом деле, никому никогда не удавалось написать какой-либо общий параллельный вид в Haskell, который был бы конкурентоспособен. Самые современные виды, предоставляемые стандартной библиотекой Haskell, обычно в сотни раз медленнее, чем обычные альтернативы.

Однако более распространенное определение функционального программирования как стиля, в котором подчеркивается использование первоклассных функций, действительно оказывается очень полезным в контексте многоядерного программирования, поскольку эта парадигма идеальна для разложения параллельных программ. Например, см. Новую функцию высшего порядка Parallel.For из пространства имен System.Threading.Tasks в .NET 4.

8 голосов
/ 08 октября 2008

При отсутствии побочных эффектов порядок оценки значения не имеет. Затем можно оценивать выражения параллельно.

6 голосов
/ 08 октября 2008

Основной аргумент состоит в том, что трудно автоматически распараллеливать языки, такие как C / C ++ / и т. Д., Потому что функции могут устанавливать глобальные переменные. Рассмотрим два вызова функций:

a = foo(b, c);
d = bar(e, f);

Хотя foo и bar не имеют общих аргументов и один не зависит от кода возврата другого, тем не менее они могут иметь зависимости, поскольку foo может устанавливать глобальную переменную (или другой побочный эффект), от которой зависит bar. *

Функциональные языки гарантируют, что foo и bar независимы: глобальных переменных и побочных эффектов нет. Поэтому foo и bar могут безопасно работать на разных ядрах автоматически, без вмешательства программиста.

4 голосов
/ 12 октября 2008

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

На практике, я думаю, что свойство «нет общего изменяемого хранилища» языков, основанное на сборке мусора и семантике копирования при изменении, облегчает добавление потоков в них. Лучшим примером, вероятно, является Erlang, который сочетает почти функциональную семантику с явными потоками.

1 голос
/ 08 октября 2008

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

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

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

двойное редактирование: кроме того, многие функциональные языки программирования десятилетиями разветвляли параллельные варианты. Они лучше используют параллельные вычисления с некоторым улучшением скорости, но они никогда не завоевывают популярность.

0 голосов
/ 12 октября 2008

Книга Программирование Erlang: Программное обеспечение для параллельного мира Джо Армстронга (создатель Erlang ) довольно много говорит об использовании Erlang для многоядерных ( / многопроцессорные) системы. Как гласит статья в википедии:

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

0 голосов
/ 08 октября 2008

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

А общие данные - это то, что вызывает половину головной боли при многопоточности.

...