Как, если вообще, делают ли процессы Erlang в Nerner Threads?

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

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

Предполагая, что это так, как это делается? Являются ли многие легкие процессы сопоставлены с одним потоком ядра?

Или существует ли другой способ решения этой проблемы?

Ответ 1

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

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

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

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

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

Ответ 2

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

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

erlang:system_flag(schedulers_online, NP) -> PrevNP

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

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

erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind

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

Ответ 3

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

Ответ 4

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

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

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

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

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

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

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