Erlang avalanche
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 12.12.06 15:03
Оценка: 534 (41)
... или почему имплементация Erlang style concurrency под обычные VM очень проблематична (“очень проблематична” – это потому что я ненавижу слово “невозможно”). Я собираюсь довольно сильно углубиться в детали (в конце концов, внимание к деталям – это то что отличает профи от любителя )

1. Хотя даже сами эрланговцы шутят, что soft real time – это “basically nothing”, тем не менее разница между soft real-time и отсутствием вообще каких-либо гарантий существенна. (Для сложных систем обеспечить SRT довольно трудно, и существуют ли вообще сложные системы с HRT я не знаю).

A hard realtime system is one which can guarantee that a certain action will always be carried out in less than a certain time. Many simple embedded systems can make hard realtime guarantees, e.g. it is possible to guarantee that a particular interrupt service routine on a Z80 CPU will never take more than 34us. It gets progressively harder to make such guarantees for more complex systems.
Many telecomms systems have less strict requirements, for instance they might require a statistical guarantee along the lines of "a database lookup takes less than 20ms in 97% of cases". Soft realtime systems, such as Erlang, let you make that sort of guarantee...
Language features which make it hard(er) for programmers to roughly estimate performance were never added to Erlang. For instance, Erlang doesn't have lazy evaluation.
--
Система с жёстким временем это такая, что опеределённое действие будет всегда завершаться в определённый промежуток времени. Множество простых встроенных систем могуть допускать жёсткие временные ограничения, например возможно гарантировать, что прерывание на CPU Z80 никогда не превысит больше 34 микросекунды. И с ростом сложности систем дать подобные гарантии всё тяжелее и тяжелее.
Много телекоммуникационный систем имеют более мягкие ограничения, например, они могут требовать статистическую гарантию скажем "поиск в базе данных требует меньше 20 милисекунд в 97% случаев". Платформы с мягким временем, такие как Эрланг, позволяют вам давать гарантии подобного рода...
В Эрланг никогда не добавлялись фичи, которые бы усложняли оценку времени выполнения. Например, в Эрланге нет ленивых вычислений.
--
(http://www.erlang.org/faq/x1138.html)

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

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

2. Первый отпечаток – это решение о том, как распределяется время среди процессов. Наприме, в есть аналогичные легковесные процессы в Питоне (stackless microthreads, Candygram), в Яве (Scala actors) и в Лиспе (Distel). В сущности, что такое параллельная программа на лёгких процессах? Грубо говоря, это большой однопоточный while (или хвостово-рекурсивный эквивалент):
while (true)
{
    int n = decide();
    work_in_process(n);
}

Функции, которые пишет программер, при компиляции будут порезаны на мелкие кусочки переходами на внешний уровень, так что поток управления неявно размазывается по функциям work_in_process(n). Очевидно, что пока work_in_process(n) не отработает, передать управление в work_in_process(n+1) мы не можем. Теперь предположим, что программер пишет
    xml_tree = xml.parse();

Внимание вопрос: как выдрать управление из функции parse и передать в work_in_process(n+1)? Если эта функция из фреймворка? Если эта функция из third-party библиотеки? Скала и Питон разводят руками. Distel – потенциально опасные функции помечаются специальным соглашением о наименовании. То же самое придётся делать с функциями, вызывающими эти, функциями второго, третьего и т.п. уровня. Такая операция замыкания на множестве функций вырежет добрую половину (если не больше) всех доступных библиотек и функций.

Файберы не решают этой проблемы, потому что внедрить переход к другому файберу в функцию parse технически трудноосуществимо. Либо похожий (скорее фантастический) вариант – послайсить тяжёлые функции по результатам предварительного прогона – то есть внедрить в их код команды возврата к шедулеру. Однако, во-первых, технически я не представляю как это сделать. Во-вторых, нужно где-то хранить контекст, чтобы потом можно было продолжить выполнение. В-третьих, у этого подхода есть жёсткие ограничения по масштабируемости. В-четвёртых, этот подход плохо подстраивается под меняющиеся условия – если какой-то участок

Остаётся одно – выдрать управление с помощью потоков ОС. Получается, от чего ушли к тому пришли.
По мне так не очень весело, а больше способов я лично не вижу.

Ситуация с Concurrent Haskell и E лучше, но там, насколько мне известно, тоже нельзя дать никаких гарантий даже в предположении идеальной операционки. Единственный конкурент – Oz (как утверждают его авторы). Однако строго говоря там другая модель параллельности ну и опять же – свой рантайм.

Эрланг – это функциональный язык реализованный на основе редукций. В то время как скажем в питоновских микропотоках или скалистых акторах квант времени определяется на основе количества выполненых инструкций байт-кода, в Эрланге квант определяется на основе количества редукций. Разница принципиальная: выполнение одной инструкции байткода может длиться от времени выполнения нескольких машинных инструкций до времени перехода Солнца из стадии жёлтого карлика в стадию красного гиганта. В то же время одна редукция выполняется _всегда_ быстро (верхняя граница существует и весьма мала; кстати поэтому в гвардах можно делать только жёстко ограниченный набор операций).

Это означает что эрланговский процесс (в противовес вышеперечисленным) не может оккупировать процессор на долгое время. Вдобавок, шедулер имеет и обеспечивает необходимую точность: _практически гарантируется_, что процесс получит управление во временном окне X (где X зависит от многих факторов, но для целевых приложений его хватает с запасом). Любой математик/программист может вывести все необходимые вероятностные оценки на время отклика и испытать их практически. Естественно, нужно учитывать вносимые флуктуации железом и операционкой. Если с практической точки зрения, нас волнует доступность сервиса, то следует учесть, что доступность и ограничения на время сильно коррелируют. Возьмите правильное железо, и правильную операционку, и при должном подходе к делу вы тоже получите девять девяток доступности, как в случае мегасвитча AXD-301.

3. “Selective receive” это три маленьких пункта:
1. Если очередь пуста, процесс блокируется.
2. Все сообщения в мэйлбоксе “паттерн-матчатся”, соответствующее сообщение удаляется из мэйлбокса и запускается обработка сообщения, которая может длиться сколь угодно долго.
3. Все сообщения в мэйлбоксе сортируются по категориям так, что наиболее приоритетные сообщения берутся первыми.
“Selective receive” имеет преимущества по сравнению с FIFO:

If one may receive input from multiple, uncoordinated senders, there is no way to predict the order in which the inputs will arrive. So you either explicitly handle all permutations, or find a way to reorder messages where applicable. This is essentially what the selective receive does...
This radically reduces the number of combinations we are forced to write code for.
--
Если процесс получает на вход сообщения от нескольких хаотических отправителей, невозможно предсказать порядок получения сообщений. Поэтому вы либо явно обрабатываете все перестановки, или находите способ перестроить сообщения для обработки. Это в сущности то, что делает selective receive...
Это значительно уменьшает количество комбинаций, для которых мы должны написать код.
--
(Ulf Wiger, http://www.erlang.org/ml-archive/erlang-questions/200606/msg00213.html)

Однако требуются значительные усилия, чтобы реализовать его эффективно. А именно, (1) как только в мэйлбокс некоторого приоритетного процесса приходит сообщения, он (процесс) должен мгновенно получить управление (прямой доступ к шедулеру), (2) чтобы разбить сообщения на категории, нужно в худшем случае сканировать весь мэйлбокс, следовательно сканирование может занять большое время, (3) в силу специфики приложений receive запросто может стать узким местом, (4) реализация receive требует некоторой возни с массивами, в частности in-place resize, а для этого нужно взаимодействие с gc.
Считаю, что этих четырёх пунктов должно быть достаточно для того, чтобы реализовать receive на уровне виртуальной машины, а не на уровне байткода.
(Подробнее про семантику selective receive читаем мегасообщение от Richard’а O’Keefe)

4. GC в Эрланге – это произведение искусства.  Ну ладно, просто классный:

Armstrong and Virding have proposed a one-pass mark-and-sweep garbage collector. The collector is designed for languages that prohibit destructive operations (i.e. values can not be overwritten), and is used in a Erlang implementation. Since destructive operations are not allowed, references can only refer to older objects. The collector marks the objects from the youngest to the oldest. If no other object has referred to an object that is being marked, it can be reclaimed immediately (since only younger objects can refer to it.) All objects are kept in a singly linked list to keep the objects in order. All GC operations have predictable runtime behavior. Thus, it can be used for real-time systems if it is scheduled to guarantee memory availability.
--
Армстронг и Вирдинг предложили однопроходной mark-and-sweep сборщик мусора. Сборщик спроектирован для языков, которые запрещают деструктивные операции (то есть значения не могут быть перезаписаны), и используется в реализации Эрланга. Поскольку деструктивные операции недопустимы, ссылки могут лишь указывать на более старые объекты. Сборщик помечает объекты начиная с самых новых и заканчивая самыми старыми. Если нет других объектов, ссылающихся на помеченный, этот объект может быть немедленно освобождён (поскольку только более новые объекты могуть на него ссылаться). Все объекты завязаны в список и образуют порядок. Все операци сборщика имеют предсказуемое время работы. Таким образом, такой сборщик может быть использован для систем реального времени чтобы гарантировать выделение памяти, если есть гарантия того, что сборщик получит управление.
--
([AV95] Joe Armstrong and Robert Virding. One-pass real-time generational mark-sweep garbage collection.)

То есть мало того, что он быстрый (один проход по списку – вот и вся сборка мусора), так ещё имеет предсказуемое время работы.
По этой теме можно также взглянуть сюда (ссыла от Cyberax )
Это ещё не всё. Чтобы увеличить независимость процессов, каждый процесс обслуживается сборщиком отдельно, то есть имеет собственную кучу. Преимущество – можно просто выбросить все данные для процесса, когда этот процесс мрёт. Расшаривание одной большой кучи может привести к более частым сборкам мусора, что нежелательно.
GC должен одинаково хорошо работать как в случае частых перезапусков процессов, так и в случае множества долгоживущих многососущих и многовыплёвывающих процессов.
В то же время, можно сделать так, что если какому-то критическому процессу не будет хватать памяти, то ему будет выделена память за счёт бездействующих процессов.
Наконец, в последнее время появилась “гибридная” модель с расшаренной кучей, где локальная посылка сообщений проходит вообще без какого-либо копирования (см. erl -hybrid) и с сохранением SRT. Это вообще принципиально э... очень проблематично без взаимодействия с gc.

5. Я конечно ляпнул про “интеллектуальность” шедулера. На самом деле он просто удовлетворяет ряду условий:

- scheduling is preemptive.
— a process is suspended if it enters a receive statement, and there is no matching message in the message queue.
— if a receive timer expires, the process is rescheduled.
---
— многозадачность вытесняющая.
— процесс останавливается всякий раз, когда он доходит до receive, и в очереди нет подходящих под паттерны сообщений.
— если время таймера (условие after в операторе receive) истекает, процесс будет перепланирован для того, чтобы первым получить time-slice.
---
(Ulf Wiger, http://www.erlang.org/ml-archive/erlang-questions/200104/msg00072.html)

Обратите внимание на первый и третий пункты. Чтобы обеспечить эти пункты, нужно иметь возможность шедулеру в любой момент получить управление (вот он SRT). И для совсем тяжёлых случаев у нас есть

In a runtime environment that supports it, it should be possible to also have erlang processes at interrupt priority (meaning that they will be allowed to run as soon as there is something for them to do — not having to wait until a 'normal' priority process finishes its timeslice.)
--
В окружении, поддерживающем прерывания, также заложена возможность иметь процессы с приоритетом "interrupt" (что означает, что они должны получить управление как только будет что-то им для выполнения — то есть нет необходимости ждать, пока процесс с нормальным приоритетом доработает до конца своего time-slice'а).
--
(Ulf Wiger, http://www.erlang.org/ml-archive/erlang-questions/200104/msg00072.html , конец сообщения)

То есть здесь конечно рулит не сам шедулер как таковой, а то что он тесно склеен с рантаймом и поэтому обеспечивает такие возможности.

Ну я надеюсь, я достаточно подробно пояснил, почему я считаю, что Эрланг невозможен под jvm/.net? Хочу правильно поставить акцент: я не отрицаю возможность lightweight библиотеки, я всего лишь навсего очень-очень сильно сомневаюсь, что она может составить конкуренцию Эрлангу на _его_ поле боя и на смежных площадях:

Telephone systems have to handle 95% of maximum supported load while being attacked with 100 times that load.
Erlang is designed for telephone systems by the biggest supplier of telephone systems in the world. It works.
--
Системы телефонии должны работать при нагрузке 95% от максимально возможной при этом выдерживать пиковую нагрузку превышающую максимальную в 100 раз. Эрланг был создан для систем телефонии самым большим поставщиком таких систем в мире. И он работает.

quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re: Erlang avalanche
От: IT Россия linq2db.com
Дата: 12.12.06 15:28
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Ну я надеюсь, я достаточно подробно пояснил, почему я считаю, что Эрланг невозможен под jvm/.net?


Т.е. фактически две причины:

— реализация вытесняющего, а не корпоративного распаралеливание как (как я понял), например, в Скала,
— однопроходный GC, с предсказуемым временем работы.

Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Erlang avalanche
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.12.06 15:58
Оценка: -1
Здравствуйте, IT, Вы писали:

IT>Т.е. фактически две причины:


IT>- реализация вытесняющего, а не корпоративного распаралеливание как (как я понял), например, в Скала,


Это можно сделать только в ОС. Эрлэнг тоже это не делает.

IT>- однопроходный GC, с предсказуемым временем работы.


Это требование для систем реального веремени. К тому же для Явы уже есть РВ-GC.

IT>Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?


Ни первое, ни второе не нужно для большинства бизнес-задач коих большинство.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Erlang avalanche
От: Курилка Россия http://kirya.narod.ru/
Дата: 12.12.06 16:02
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Lazy Cjow Rhrr, Вы писали:


LCR>>Ну я надеюсь, я достаточно подробно пояснил, почему я считаю, что Эрланг невозможен под jvm/.net?


IT>Т.е. фактически две причины:


IT>- реализация вытесняющего, а не корпоративного распаралеливание как (как я понял), например, в Скала,

IT>- однопроходный GC, с предсказуемым временем работы.

IT>Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?


Реализовать ты сможешь, только SRT гарантировать будет по меньшей мере очень сложно. На той же Скале я напишу в коде актора бесконечный цикл и он "съест" поток.
Как реализовать гранулируемость до чего нибудь уровня редукций — очень хороший вопрос. Возможно это можно сделать на Немерле путём работы с АСТ.
Плюс ещё надо реализовать достаточно эффективный шедулер.

Кстати на Скала сейчас они уже сделали пересылку сообщений между JVM, только вот ресив там постоянно сидит в цикле и поллит результаты, т.е. 100% загрузку ЦПУ получаем. Надо будет написать авторам, какие у них планы по развитию этого детища
Re[2]: Erlang avalanche
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 12.12.06 16:16
Оценка: 2 (2)
IT,

IT>Т.е. фактически две причины:


IT>- реализация вытесняющего, а не корпоративного распаралеливание как (как я понял), например, в Скала,

IT>- однопроходный GC, с предсказуемым временем работы.

IT>Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?


Если мы говорим о любительской реализации, где мы готовы забить на эффективность и все библиотеки (будем пользоваться только нашими спец-функциями), то
0. Ничего не мешает.
(За прототип можно взять Distel — программа преобразуется с помощью макросов к CPS и на каждом таймслайсе выполняется несколько сотен редукций).

Если мы говорим о промышленной реализации, то причин чуть больше. Для промышленной реализации нам нужны следующие вещи:
1. Библиотеки.
2. Возможность ставить временные ограничения.
3. Критические примитивы, реализованные на уровне ВМ.
4. Тесное взаимодействие с gc.

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

(но ты подожди радоваться, может я ещё чего вспомню )

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

 (Various kinds of) locks and monitors
 STM's
 Pi-calculus and CCS
 CSP, Occam
 Asychronous Pi-calculus, Pict
 Join calculus, functional nets, JoCaml, polyphonic C#.
 Concurrent logic programming, Oz
 Actors, Erlang
 CML synchronous events
 Ada rendezvous
--
Martin Odersky "Tackling Concurrency — Language or Library?"

О, смотри! Мы можем выбрать первый пункт и вообще ничего не делать!
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Erlang avalanche
От: Cyberax Марс  
Дата: 12.12.06 16:22
Оценка: +1 :))) :)
IT wrote:
> Т.е. фактически две причины:
Их больше

> — реализация вытесняющего, а не корпоративного распаралеливание как (как

> я понял), например, в Скала,
Корпоративное распараллеливание — это когда директор говорит 100
подчиненным что-нибудь сделать.

Есть кооперативное распараллеливание. В Скале не совсем оно, как
я понял.

> — однопроходный GC, с предсказуемым временем работы.

> Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?
Мутабельность переменных.
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[3]: Erlang avalanche
От: Курилка Россия http://kirya.narod.ru/
Дата: 12.12.06 16:35
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>IT wrote:

>> — однопроходный GC, с предсказуемым временем работы.
>> Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?
C>Мутабельность переменных.

Ты перепутал, эт ко второму относится. Мутабельность на самом распараллеливании напрямую не сказывается, вроде как
Re[4]: Erlang avalanche
От: Cyberax Марс  
Дата: 12.12.06 16:54
Оценка:
Курилка wrote:
>> > — однопроходный GC, с предсказуемым временем работы.
>> > Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?
> C>Мутабельность переменных.
> Ты перепутал, эт ко второму относится. Мутабельность на самом
> распараллеливании напрямую не сказывается, вроде как
Я про однопроходность GC говорил.
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[3]: Erlang avalanche
От: IT Россия linq2db.com
Дата: 12.12.06 17:04
Оценка:
Здравствуйте, Курилка, Вы писали:

IT>>Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?


К>Реализовать ты сможешь, только SRT гарантировать будет по меньшей мере очень сложно. На той же Скале я напишу в коде актора бесконечный цикл и он "съест" поток.


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

К>Как реализовать гранулируемость до чего нибудь уровня редукций — очень хороший вопрос. Возможно это можно сделать на Немерле путём работы с АСТ.


АСТ тут не причём. Вытесняющая многозадачность возможна только насильственным путём, когда у рабочего потока никто ничего не спрашивает.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Erlang avalanche
От: IT Россия linq2db.com
Дата: 12.12.06 17:08
Оценка: :)
Здравствуйте, Cyberax, Вы писали:

C>Есть кооперативное распараллеливание. В Скале не совсем оно, как

C>я понял.

О! Точно, коперативное. Я уже и забыл как это называется.

>> — однопроходный GC, с предсказуемым временем работы.

>> Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?
C>Мутабельность переменных.

А это тут каким боком? Мутабельность уже учтена в GC.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Erlang avalanche
От: Cyberax Марс  
Дата: 12.12.06 18:39
Оценка: 54 (7)
IT wrote:
>> > — однопроходный GC, с предсказуемым временем работы.
>> > Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?
> C>Мутабельность переменных.
> А это тут каким боком? Мутабельность уже учтена в GC.
Про упрощение generational GC я уже писал, теперь напишу про трехцветный
GC

Предположим, что у нас есть граф объектов. Изначально все узлы графа
покрашены в белый цвет.

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

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

У этого алгоритма получается "tri-color invariant" — черные узлы не
могут указывать напрямую на белые узлы. Кстати, это база почти всех
инкрементальных алгоритмов GC.

Теперь, если у нас все переменные иммутабельны, то GC сильно упрощается
— уже помеченные черным узлы не могут поменять свой цвет! Смена цвета
происходит в том случае, если к уже существующему объекты добавляется
новая ссылка, но объекты у нас иммутабельны.

Таким образом, мы можем вместо двух проходов (покраска в серый цвет, а
потом в черный) оставить только один (покраска в черный цвет).

Теоретически, этот алгоритм можно добавить в GC для CLR/JVM — но он
будет работать только на кластерах иммутабельных объектов. А выделение
таких кластеров (без хинтов GC) — сама по себе непростая задача
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[3]: Erlang avalanche
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.12.06 18:43
Оценка: :)
Здравствуйте, VladD2, Вы писали:

IT>>- реализация вытесняющего, а не корпоративного распаралеливание как (как я понял), например, в Скала,


VD>Это можно сделать только в ОС. Эрлэнг тоже это не делает.


Э... блин, запутали вы меня. Вытесняющая — это приоритеты. Это конечно можно сделать где угодно. Я имел в виду реальный параллилизм. В общем, не о том подумал. Сори.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Erlang avalanche
От: IT Россия linq2db.com
Дата: 12.12.06 22:00
Оценка:
Здравствуйте, Cyberax, Вы писали:

>>> > — однопроходный GC, с предсказуемым временем работы.

>>> > Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?
>> C>Мутабельность переменных.
>> А это тут каким боком? Мутабельность уже учтена в GC.
C>Про упрощение generational GC я уже писал, теперь напишу про трехцветный
C>GC

Это всё понятно, immutable — это хорошо для GC. Что у нас с реализацией вытесняющей многозадачности?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Erlang avalanche
От: Cyberax Марс  
Дата: 12.12.06 22:48
Оценка:
IT wrote:
>> > А это тут каким боком? Мутабельность уже учтена в GC.
> C>Про упрощение generational GC я уже писал, теперь напишу про трехцветный
> C>GC
> Это всё понятно, immutable — это хорошо для GC. Что у нас с реализацией
> вытесняющей многозадачности?
Это смотря с какой стороны смотреть.

Если со стороны приложения, то Эрланг дает вытесняющую многозадачность —
поток приложения может быть в "любой момент" вытеснен другим потоком
(насколько я помню, там планировщик каждые ~100 редукций запускается).

Если смотреть со стороны ОС — то Эрланг представляет собой однопоточное
приложение (точнее, уже многопоточное на SMP).
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[4]: Erlang avalanche
От: Курилка Россия http://kirya.narod.ru/
Дата: 13.12.06 07:27
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Курилка, Вы писали:


IT>>>Со вторым понятно. А что делает невозможным реализацию первого в JVN/CLR?


К>>Реализовать ты сможешь, только SRT гарантировать будет по меньшей мере очень сложно. На той же Скале я напишу в коде актора бесконечный цикл и он "съест" поток.


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


В том и вопрос — как его туда вставить и как проконтроллировать "неподвластные" вещи.

К>>Как реализовать гранулируемость до чего нибудь уровня редукций — очень хороший вопрос. Возможно это можно сделать на Немерле путём работы с АСТ.


IT>АСТ тут не причём. Вытесняющая многозадачность возможна только насильственным путём, когда у рабочего потока никто ничего не спрашивает.


ОК, как ты будешь в виртуальной машине такое делать? Не используя потоки ОС? Если ты будешь вставлять в циклы код передачи управления шедулеру, то это у нас не будет вмешательством в АСТ?
Как можно сделать такое на Скале не переделывая компилятор я не вижу. Зато по-моему это нетак сложно реализовать на макросах, если ты имеешь контроль над генерируемым в итоге кодом.
Re[5]: Erlang avalanche
От: n0name2  
Дата: 13.12.06 12:04
Оценка:
К>ОК, как ты будешь в виртуальной машине такое делать? Не используя потоки ОС? Если ты будешь вставлять в циклы код передачи управления шедулеру, то это у нас не будет вмешательством в АСТ?
К>Как можно сделать такое на Скале не переделывая компилятор я не вижу. Зато по-моему это нетак сложно реализовать на макросах, если ты имеешь контроль над генерируемым в итоге кодом.

В чем проблема? Инструментируем байт код (при загрузке), в т.ч. байт код Java библиотек. Допустим, вставляем туда обращение к шедулеру при каждом 10м вызове метода.

Кстати, а редукции в Erlang имеют гарантированное время выполнения? Т.е. может одна редукция выполняться полчаса?
Re[6]: Erlang avalanche
От: Курилка Россия http://kirya.narod.ru/
Дата: 13.12.06 12:15
Оценка:
Здравствуйте, n0name2, Вы писали:

К>>ОК, как ты будешь в виртуальной машине такое делать? Не используя потоки ОС? Если ты будешь вставлять в циклы код передачи управления шедулеру, то это у нас не будет вмешательством в АСТ?

К>>Как можно сделать такое на Скале не переделывая компилятор я не вижу. Зато по-моему это нетак сложно реализовать на макросах, если ты имеешь контроль над генерируемым в итоге кодом.

N>В чем проблема? Инструментируем байт код (при загрузке), в т.ч. байт код Java библиотек. Допустим, вставляем туда обращение к шедулеру при каждом 10м вызове метода.


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

N>Кстати, а редукции в Erlang имеют гарантированное время выполнения? Т.е. может одна редукция выполняться полчаса?


Насколько я понимаю да, в смысле не может. Т.к. это гарантируется рантаймом, устройством библиотек и портов (с помощью которых происходит общение с вн. миром).
Как минимум в эрланге нет циклов, поэтому если не выполнять функции (что приведёт к вызову др. редукций), то единственный способ сделать задержку это написать кучу присваиваний каких-нибудь, но даже в этом случае у тебя будет конечное время (и хз какой у тебя должен быть бимфайл чтобы полчаса получилось). Т.е. как минимум надо очень-очень постараться. Причём я не знаю может есть какое-то ограничение на длину функции/бимфайла, просто практически такое никто не делает, они довольно маленькие по объёму.
В императивном же байткоде тебе сделать беск. цикл можно вполне просто, в этом и возникает проблемка.
Re[7]: Erlang avalanche
От: n0name2  
Дата: 13.12.06 12:38
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Т.е. надо в рантайме перехреначить байткод. Мне кажется, что АСТ курочить полегче будет.

К>Т.е. у тебя тут получится, что будет выполняться не байткод, а уже какой-то перетранслированный.

Не, как раз для этого есть куча средств. Сделать чтобы ВСЕ методы у ВСЕХ библиотек перед началом работы вызывали scheduler это 2-3 строчки кода, плюс добавить библиотеку и изменить startup script. И вообще, байткод гораздо проще чем AST языка. Правда, конечно, stack trace будет весьма странный получатся, что осложнит отладку довольно сильно.

К>В императивном же байткоде тебе сделать беск. цикл можно вполне просто, в этом и возникает проблемка.


В принципе, трансформировать байт код так, чтобы в циклы вставлялся тоже вызов scheduler — не проблема. Правда, сейчас пока для этого соотв-ие хуки JVM не предоставляет, так что придется немного повозится. Но, это довольно просто.

Проблема может быть, конечно если у нас synchronized блок и в нем цикл, нужно будет делать wait() чтобы освободить монитор. Тут я не уверен что все сходу правильно получится.

Но, вообще — проще вернуть green threads, вот и все. Собственно, насколько я понию, их так и не убрали из JVM. Только вот никакого особенного эффекта на типовых задачах они не дают, поэтому их и убрали.

Честно говоря, вообще я не очень понимаю зачем нужно все это. В Java такого рода задачи делаются немного по другому — заводится пул потоков (практически это OS threads, размер пула определяется исходя из кол-во CPU), и есть входная очередь задач. Соот-но поток взял очередную задачу, обработал ее, взялся за следующую. Особо криминального переключения контекстов или оверхеда на создание тысяч потоков тут нет.
Re[8]: Erlang avalanche
От: Курилка Россия http://kirya.narod.ru/
Дата: 13.12.06 12:57
Оценка:
Здравствуйте, n0name2, Вы писали:

N>Здравствуйте, Курилка, Вы писали:


К>>Т.е. надо в рантайме перехреначить байткод. Мне кажется, что АСТ курочить полегче будет.

К>>Т.е. у тебя тут получится, что будет выполняться не байткод, а уже какой-то перетранслированный.

N>Не, как раз для этого есть куча средств. Сделать чтобы ВСЕ методы у ВСЕХ библиотек перед началом работы вызывали scheduler это 2-3 строчки кода, плюс добавить библиотеку и изменить startup script. И вообще, байткод гораздо проще чем AST языка. Правда, конечно, stack trace будет весьма странный получатся, что осложнит отладку довольно сильно.


ОК, что ты сделаешь с нативными библиотеками?

N>Честно говоря, вообще я не очень понимаю зачем нужно все это. В Java такого рода задачи делаются немного по другому — заводится пул потоков (практически это OS threads, размер пула определяется исходя из кол-во CPU), и есть входная очередь задач. Соот-но поток взял очередную задачу, обработал ее, взялся за следующую. Особо криминального переключения контекстов или оверхеда на создание тысяч потоков тут нет.


А сотен тысяч? Причём кратковременных, когда значительным может быть время создания/убивания потока?
Переключение контекста тоже вещь не бесплатная совсем, если выполняется на 1 проце.
Для "обычных" задач конечно условия такие не наблюдаются, но они и проектируются изначально иначе, на постоянные пулы и т.д.
Re[9]: Erlang avalanche
От: n0name2  
Дата: 13.12.06 13:21
Оценка:
Здравствуйте, Курилка, Вы писали:

К>ОК, что ты сделаешь с нативными библиотеками?


Ничего. В Java они практически нигде не используются. Это большая экзотика если речь идет о типовом бизнес приложении. Разве что — есть ввод/вывод и другие native вызовы в самом JDK, но, они все-таки много времени обычно не занимают и т.к. это SRT то можно ими пренебречь. Кстати, как проблема ввода/вывода в Erlang решается применительно к scheduling?

N>>Честно говоря, вообще я не очень понимаю зачем нужно все это. В Java такого рода задачи делаются немного по другому — заводится пул потоков (практически это OS threads, размер пула определяется исходя из кол-во CPU), и есть входная очередь задач. Соот-но поток взял очередную задачу, обработал ее, взялся за следующую. Особо криминального переключения контекстов или оверхеда на создание тысяч потоков тут нет.


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


А зачем поток каждый раз создавать? Ведь можно завести несколько (2-4) потоков, которые обрабатывают общую очередь запросов (mailbox в терминах Erlang).

К>Для "обычных" задач конечно условия такие не наблюдаются, но они и проектируются изначально иначе, на постоянные пулы и т.д.


О чем и речь — собственно, пулы потоков это обычная практика. Я согласен — JVM не для всех классов задач подходит, no silver bullet так сказать, но, мне кажется, что если реально задача не решается с помощью пула потоков, то это большая экзотика. Пожалуйста, приведи пример (только не академический а из реального, желательно не телеком, бизнеса) такой задачи.

Тотже эксперемент с green threads очень показателен — очевидно, что scheduling в стиле Erlang сделать для JVM довольно легко, но, толку это особого не даст для типовых задач. Кстати, от green threads отказались после того, как scheduler в Linux стал работать гораздо лучше и для типовых задач разница стала незаметной.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.