Как, если вообще, процессы Erlang отображаются на потоки ядра? - PullRequest
48 голосов
/ 03 марта 2009

Эрланг известен тем, что способен поддерживать МНОГО легковесных процессов; он может сделать это, потому что это не процессы в традиционном смысле или даже потоки, как в P-потоках, а потоки исключительно в пользовательском пространстве.

Это хорошо и здорово (на самом деле фантастика). Но как тогда потоки Erlang выполняются параллельно в многоядерной / многопроцессорной среде? Конечно, они должны быть каким-то образом сопоставлены с потоками ядра, чтобы выполняться на отдельных ядрах?

Если это так, как это сделать? Много ли легких процессов сопоставлено с одним потоком ядра?

Или есть другой способ обойти эту проблему?

Ответы [ 4 ]

62 голосов
/ 03 марта 2009

Ответ зависит от используемой виртуальной машины:

1) non-SMP : существует один планировщик (поток ОС), который выполняет все процессы Erlang, взятые из пула исполняемых процессов ( то есть те, кто не заблокирован, например receive)

2) SMP : есть K планировщиков (потоки ОС, K обычно это число ядер ЦП), которые выполняют процессы Erlang из очереди общих процессов . Это простая очередь FIFO (с блокировками для одновременного доступа из нескольких потоков ОС).

3) SMP в R13B и новее : будут K планировщиков (как и прежде), которые выполняют процессы Erlang из нескольких очередей процессов . Каждый планировщик имеет свою очередь, поэтому будет добавлен процесс логика миграции из одного планировщика в другой. Это решение повысит производительность за счет избежания чрезмерной блокировки в очереди общих процессов.

Для получения дополнительной информации см. этот документ , подготовленный Кеннетом Лундином, Ericsson AB, для Erlang User Conference, Стокгольм, 13 ноября 2008 г.

10 голосов
/ 01 мая 2009

Я хочу изменить предыдущие ответы.

Erlang, или, точнее, система времени исполнения Erlang (erts), по умолчанию устанавливает количество планировщиков (потоков ОС) и количество очередей на количество элементов обработки на вашей платформе. То есть ядра процессоров или аппаратные потоки. Вы можете изменить эти настройки во время выполнения, используя:

erlang:system_flag(schedulers_online, NP) -> PrevNP

Процессы Эрланга еще не связаны ни с какими планировщиками. Логика, балансирующая процессы между планировщиками, следует двум правилам. 1) Голодный планировщик украдет работу у другого планировщика. 2) Миграционные пути настроены так, чтобы проталкивать процессы из планировщиков с большим количеством процессов в планировщики с меньшим количеством работы. Это делается для обеспечения справедливости в подсчете сокращения (времени выполнения) для каждого процесса.

Однако планировщики могут быть привязаны к конкретным элементам обработки. Это не сделано по умолчанию. Чтобы позволить erts делать scheduler-> core affinity, используйте:

erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind

Несколько других типов привязки можно найти в документации. Использование сходства может значительно улучшить производительность в ситуациях с большой нагрузкой! Особенно в ситуациях с высокой блокировкой. Кроме того, ядро ​​Linux не может обрабатывать гиперпотоки по меньшей мере. Если у вас есть гиперпотоки на вашей платформе, вы действительно должны использовать эту функцию в erlang.

1 голос
/ 18 ноября 2014

Я хотел бы добавить некоторые данные к тому, что было описано в принятом ответе.

Erlang Scheduler является неотъемлемой частью Erlang Runtime System и предоставляет собственную абстракцию и реализацию концепции облегченных процессов поверх потоков ОС.

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

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

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

Я бы порекомендовал отличное сообщение на эту тему от Jesper Louis Andersen http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html

В качестве краткого ответа: процессы Erlang не являются потоками ОС и не отображаются на них напрямую. Планировщики Erlang - это то, что работает в потоках ОС и обеспечивает разумную реализацию более мелких процессов Erlang, скрывая эти детали на глазах программиста.

1 голос
/ 03 марта 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...