Вопрос

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

Erlang — это коммерчески проверенный отказоустойчивый язык с развитой моделью распространения.У него есть, казалось бы, уникальная особенность: возможность обновлять свою версию во время выполнения посредством горячей загрузки кода.(Как круто!)

С другой стороны, Haskell имеет самую сложную систему типов среди всех основных языков.(Где я определяю «основной поток» как любой язык, на котором есть опубликованная книга О'Рейли, поэтому Haskell учитывается.) Его прямая однопоточная производительность выглядит лучше, чем у Erlang, а его легкие потоки выглядят даже легче.

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

  1. Я хотел бы использовать Erlang как своего рода отказоустойчивый MPI для объединения экземпляров среды выполнения GHC.В каждой среде выполнения GHC будет один процесс Erlang.Если «произошло невозможное» и среда выполнения GHC умерла, то процесс Erlang каким-то образом обнаружит это и тоже умрет.Функции загрузки и распространения горячего кода Erlang будут продолжать работать.Среду выполнения GHC можно настроить для использования только одного ядра или всех ядер на локальном компьютере или любой промежуточной комбинации.После написания библиотеки Erlang остальная часть кода уровня Erlang должна быть чисто шаблонной и автоматически генерироваться для каждого приложения.(Возможно, с помощью Haskell DSL, например.) Как можно достичь хотя бы некоторых из этих целей?
  2. Я бы хотел, чтобы Erlang и Haskell могли использовать один и тот же сборщик мусора.(Это гораздо более продвинутая идея, чем идея 1.) Языки, работающие на JVM и CLR, достигают большей массы за счет совместного использования среды выполнения.Я понимаю, что существуют технические ограничения на запуск Erlang (горячая загрузка кода) и Haskell (полиморфизм более высокого порядка) как на JVM, так и на CLR.А как насчет разделения только сборщика мусора?(Что-то вроде запуска среды выполнения для функциональных языков.) Очевидно, что распределение все равно должно быть очень быстрым, поэтому, возможно, этот бит необходимо будет статически скомпоновать.И должен быть какой-то механизм, позволяющий отличать изменяемую кучу от неизменяемой кучи (включая ленивую однократную запись в память), поскольку это необходимо GHC.Будет ли возможно модифицировать HIPE и GHC, чтобы сборщики мусора могли совместно использовать кучу?

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

Обновлять

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

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

На платформе, которую я предложил выше, я бы писал только Haskell, поскольку шаблонный Erlang генерировался бы автоматически.Так как долго продержится Haskell?Что ж, Lisp все еще с нами и, похоже, не исчезнет в ближайшее время.Haskell имеет открытый исходный код BSD3 и достиг критической массы.Если само программирование будет существовать и через 50 лет, я ожидаю, что Haskell или какая-то непрерывная эволюция Haskell все еще будет здесь.

Обновление 2 в ответ на сообщение rvirding

Согласен: реализация полноценной универсальной виртуальной машины «Erskell/Haslang» не может быть абсолютно невозможной, но, безусловно, это действительно будет очень сложно.Совместное использование только уровня сборщика мусора как нечто вроде виртуальной машины, но при этом трудный, Хотя для меня это звучит на порядок проще.В модели сборки мусора функциональные языки должны иметь много общего — недвусмысленность неизменяемых данных (включая переходники) и требование очень быстрого распределения.Поэтому тот факт, что общность тесно связана с монолитными виртуальными машинами, кажется странным.

Виртуальные машины действительно помогают достичь критической массы.Просто посмотрите, как стали популярны «облегченные» функциональные языки, такие как F # и Scala.Scala, возможно, не обладает абсолютной отказоустойчивостью Erlang, но она предлагает путь отхода для очень многих людей, которые привязаны к JVM.

В то время как одна куча делает сообщения очень быстро, он представляет ряд других проблем, в основном, что выполнение GC становится более трудным, поскольку оно должно быть интерактивным и глобально непрерывным, поэтому вы не можете использовать те же самые простые алгоритмы, что и Per- Процесс кучи модели.

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

http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel-gc/par-gc-ismm08.pdf

(Очевидно, что «остановить мир» не подойдет для общего Эрланга, учитывая его основной вариант использования.) Но даже в тех случаях, когда «остановить мир» допустимо, их ускорение не кажется универсальным.Так что я с вами согласен, вряд ли существует универсально лучший GC, именно поэтому я указал в части 1.моего вопроса, что

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

Таким образом, для данного варианта использования я мог бы после сравнительного тестирования выбрать путь Erlang и запустить одну среду выполнения GHC (с однопоточным GC) плюс один процесс Erlang на ядро ​​и позволить Erlang копировать память между ядрами для обеспечения хорошей локальности. .

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

В обоих случаях, если бы Erlang и GHC могли совместно использовать кучу, совместное использование, вероятно, каким-то образом было бы привязано к одному потоку ОС, работающему на одном ядре.(Здесь я ухожу в глубину своей темы, поэтому и задал вопрос.)

У меня также есть еще одна задача — тестирование функциональных языков независимо от GC.Часто читаю результаты тестов OCaml v GHC v Erlang v...и задаться вопросом, насколько результаты путаются в разных сборщиках мусора.Что, если выбор GC может быть ортогонален выбору функционального языка?Насколько дорого стоит GC?См. этот пост в блоге защитников дьявола.

http://john.freml.in/garbage-collection-harmful

мой друг по Лиспу Джон Фремлин, который очаровательно назвал свой пост «Автоматическая сборка мусора — это чушь».Когда Джон утверждает, что GC медленный и на самом деле не так сильно ускорился, я хотел бы иметь возможность опровергнуть некоторые цифры.

Это было полезно?

Решение

Многие люди, использующие Haskell и Erlang, интересуются моделью, в которой Erlang контролирует распределение, в то время как Haskell запускает узлы общей памяти параллельно, выполняя всю обработку чисел/логику.

Началом этого является библиотека haskell-erlang: http://hackage.haskell.org/package/erlang

Аналогичные усилия мы предпринимаем и на территории Ruby, через Hubris: http://github.com/mwotton/Hubris/tree/master

Теперь вопрос заключается в том, чтобы найти кого-то, кто действительно протолкнет взаимодействие Erlang/Haskell и выявит сложные проблемы.

Другие советы

Вы весело проведете время, смешивая GC с Haskell и Erlang.Erlang использует кучу для каждого процесса и копирует данные между процессами - поскольку в Haskell даже нет концепции процессов, я не уверен, как бы вы сопоставили этот «универсальный» GC между ними.Кроме того, для достижения наилучшей производительности Erlang использует различные распределители, каждый из которых имеет слегка измененное поведение, которое, я уверен, повлияет на подсистему GC.

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

Итог – ощутите разницу!Есть огромные преимущества в том, чтобы НЕ запускать все в одном процессе, особенно с точки зрения надежности.Кроме того, я думаю, немного наивно ожидать, что один язык/VM прослужит вам всю оставшуюся жизнь (если только вы не планируете а.) прожить короткое время или б.) стать своего рода кодовым монахом, который работает ТОЛЬКО на один проект).Разработка программного обеспечения — это умственная гибкость и готовность использовать лучшие доступные инструменты для создания быстрого и надежного кода.

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

Предстоящий платформа распределенных процессов Библиотека добавляет поддержку конструкций в стиле OTP, таких как gen_servers, деревья контроля и различные другие абстракции со вкусом Haskell, заимствованные и вдохновленные Erlang/OTP.

  1. Вы можете использовать процесс OTP gen_supervisor для мониторинга экземпляров Haskell, которые вы создаете с помощью open_port().В зависимости от того, как «порт» завершился, вы сможете перезапустить его или решить, что он остановился намеренно и позволить соответствующему процессу Erlang тоже умереть.

  2. Фугеддабудит.Даже у этих независимых от языка виртуальных машин, о которых вы говорите, иногда возникают проблемы с данными, передаваемыми между языками.Вам следует просто каким-то образом сериализовать данные между ними:база данных, XML-RPC, что-то в этом роде.

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

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

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

Пока мы используем неизменяемые структуры данных, проблем с надежностью и безопасностью не возникает.Решение о том, какие модели памяти и GC использовать, является большим компромиссом, и, к сожалению, существует универсальная лучшая модель.

Хотя Haskell и Erlang являются функциональными языками, они во многих отношениях очень разные языки и имеют очень разные реализации.Было бы сложно придумать машину «Эрскелл» (или Хасланг), которая могла бы эффективно обрабатывать оба языка.Лично я считаю, что гораздо лучше держать их отдельно и обеспечить действительно хороший интерфейс между ними.

CLR поддерживает оптимизацию хвостовых вызовов с явным tail код операции (используемый F#), которому JVM (пока) не имеет эквивалента, что ограничивает реализацию такого стиля языка.Использование отдельных AppDomains позволяет CLR выполнять горячую замену кода (см., например, этот пост в блоге показать, как это можно сделать).

Поскольку Саймон Пейтон Джонс работает чуть дальше по коридору от Дона Сайма и команды F# в Microsoft Research, было бы большим разочарованием, если бы мы в конечном итоге не увидели IronHaskell с каким-то официальным статусом.IronErlang был бы интересным проектом — самой большой частью работы, вероятно, было бы портирование планировщика с зелеными потоками, не утяжеляя его, как движок Windows Workflow, или не запуская виртуальную машину BEAM поверх CLR.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top