Характеристики Эрланга
Из Erlang Programming (2009):
Эрлангский параллелизм быстрый и масштабируемый. Его процессы легки в том, что виртуальная машина Erlang не создает поток ОС для каждого созданного процесса. Они создаются, планируются и обрабатываются в виртуальной машине независимо от базовой операционной системы. В результате время создания процесса составляет порядка микросекунд и не зависит от числа одновременно существующих процессов. Сравните это с Java и C #, где для каждого процесса создается базовый поток ОС: вы получите несколько очень конкурентоспособных сравнений, причем Erlang значительно превосходит оба языка.
Из ориентированного на параллелизм программирования в Erlang (pdf) (слайды) (2003):
Мы отмечаем, что время, необходимое для создания процесса Эрланга, составляет от 1 мкс до 2500 процессов; после этого он увеличивается примерно до 3 мкс до 30 000 процессов. Производительность Java и C # показана в верхней части рисунка. Для небольшого числа процессов создание процесса занимает около 300 мкс. Создание более двух тысяч процессов невозможно.
Мы видим, что для 30 000 процессов время отправки сообщения между двумя процессами Erlang составляет около 0,8 мкс. Для C # требуется около 50 мкс на сообщение, до максимального количества процессов (которое составляло около 1800 процессов). Java была еще хуже: на 100 процессов приходилось около 50 мкс на сообщение, после чего она быстро увеличивалась до 10 мс на сообщение, когда было около 1000 Java-процессов.
Мои мысли
Я не совсем понимаю, с технической точки зрения, почему процессы Эрланга намного эффективнее порождают новые процессы и имеют гораздо меньшие объемы памяти на процесс. И ОС, и Erlang VM должны выполнять планирование, переключение контекста и отслеживать значения в регистрах и так далее ...
Просто почему потоки ОС не реализуются так же, как процессы в Erlang? Должны ли они поддерживать что-то большее? И зачем им больше памяти? И почему у них медленнее нерест и общение?
Технически, почему процессы в Erlang более эффективны, чем потоки ОС, когда речь идет о порождении и коммуникации? И почему потоки в ОС не могут быть реализованы и управляться так же эффективно? И почему потоки ОС занимают больше места в памяти, а также медленнее порождают и общение?
erl +P 1000100 +hms 100
напечатайте{_, PIDs} = timer:tc(lists,map,[fun(_)->spawn(fun()->receive stop -> ok end end) end, lists:seq(1,1000000)]).
и затем подождите около трех минут, чтобы получить результат. Это так просто. Это занимает 140 мкс на процесс и 1 ГБ оперативной памяти на моем ноутбуке. Но это непосредственно оболочка, лучше скомпилированный код.Ответы:
Есть несколько способствующих факторов:
источник
После еще одного исследования я нашел презентацию Джо Армстронга.
От Erlang - программное обеспечение для параллельного мира (презентация) (в 13 мин):
Я думаю, что он отвечает, если не все, по крайней мере, на несколько моих вопросов
источник
Я реализовал сопрограммы в ассемблере и измерил производительность.
Переключение между сопрограммами, или процессами Эрланга, занимает около 16 инструкций и 20 наносекунд на современном процессоре. Кроме того, вы часто знаете процесс, на который вы переключаетесь (пример: процесс, получающий сообщение в своей очереди, может быть реализован как прямая передача вызова от вызывающего процесса к процессу получения), поэтому планировщик не вступает в игру, делая это операция O (1).
Чтобы переключать потоки ОС, требуется около 500-1000 наносекунд, потому что вы обращаетесь к ядру. Планировщик потоков ОС может выполняться за O (log (n)) или O (log (log (n))), что станет заметно, если у вас десятки тысяч или даже миллионы потоков.
Следовательно, процессы Erlang быстрее и лучше масштабируются, потому что как основная операция переключения выполняется быстрее, так и планировщик работает реже.
источник
Эрланговские процессы соответствуют (приблизительно) зеленым нитям на других языках; нет никакого принудительного разделения между процессами. (Возможно, существует разделение по языку, но это меньшая защита, несмотря на то, что Эрланг выполняет лучшую работу, чем большинство.) Поскольку они намного легче, их можно использовать гораздо шире.
Потоки ОС, с другой стороны, могут быть просто запланированы на разные ядра ЦП и (в основном) способны поддерживать независимую обработку, связанную с ЦП. Процессы ОС похожи на потоки ОС, но с гораздо более сильным разделением на основе ОС. Цена этих возможностей заключается в том, что потоки ОС и (тем более) процессы стоят дороже.
Еще один способ понять разницу заключается в следующем. Предположим, что вы собираетесь написать реализацию Erlang поверх JVM (не очень сумасшедшее предложение), тогда вы сделаете каждый процесс Erlang объектом с некоторым состоянием. Затем у вас будет пул экземпляров Thread (обычно измеряемый в соответствии с количеством ядер в вашей хост-системе; это настраиваемый параметр в реальных средах исполнения Erlang, кстати), которые запускают процессы Erlang. В свою очередь, это распределит работу, которая должна быть сделана, по реальным доступным системным ресурсам. Это довольно аккуратный способ ведения дел, но полностьюна факте, что каждый отдельный процесс Эрланга не делает очень много. Это нормально, конечно; Erlang структурирован так, чтобы не требовать, чтобы эти отдельные процессы были тяжеловесными, поскольку весь их ансамбль выполняет программу.
Во многих отношениях настоящая проблема заключается в терминологии. То, что Эрланг называет процессами (и которые строго соответствуют одному и тому же понятию в CSP, CCS и особенно π-исчислении), просто не совпадает с тем, что языки с наследием C (включая C ++, Java, C # и многие другие) называют процесс или поток. Есть некоторые сходства (все включают некоторое понятие параллельного выполнения), но определенно нет эквивалентности. Так что будьте осторожны, когда кто-то говорит вам «процесс»; они могут понять, что это означает что-то совершенно другое ...
источник
Я думаю, что Джонасу нужны были цифры для сравнения потоков ОС с процессами Эрланга. Джо Армстронг, автор Programming Erlang, некоторое время назад проверил масштабируемость процессов Erlang в потоках ОС. Он написал простой веб-сервер на Erlang и протестировал его на многопоточном Apache (поскольку Apache использует потоки ОС). Есть старый сайт с данными за 1998 год. Мне удалось найти его только один раз. Поэтому я не могу предоставить ссылку. Но информация там. Суть исследования показала, что Apache максимально справился с процессами под 8K, в то время как его рукописный сервер Erlang обрабатывал процессы с 10K +.
источник
Поскольку интерпретатору Erlang нужно беспокоиться только о себе, в ОС есть много других проблем.
источник
одна из причин заключается в том, что процесс erlang создается не в ОС, а в evm (виртуальная машина erlang), поэтому его стоимость меньше.
источник