То есть все userspace треды в итоге будут мапиться только на один физический? Спасибо, не надо.
+ Как будете переключать стек/регистры без оверхеда на системные вызовы?
Конечно, подобный софт можно написать хоть на brainfuck'e если позволяет опыт и аккрутаность. Но дело вот в чем: на С++ создание безотказного приложения - это гемор тот еще, а на Erlang'e это все «из коробки» и никакого «защитного» программирования нет. Имхо, фирме дешевле железа докупить, чем оплачивать работу высококвалифицированного программиста. Так что пусть Erlang медленнее, но масштабируемость + скорость разработки решает.
просто не обязательно плодить столько потоков. это ошибка в проектировании или лень программистов.
например, если пул тасков и их можно обрабатывать в сотне потоков. эффективность будет выше. это стандартное решение для обработки множества коннектов.
Не написал, но являюсь соавтором нескольких erlang-овых проектов. Сбор и парсинг Netflow, свертки полученных данных. СМС-гейт. SCADA. Все это сугубо телекомовские задачи, язык очень хорошо ложится на их специфику.
насчёт «дешевле железа закупить» не соглашусь. наш отдел разработки создан именно с целью избавиться от мейнфреймов (которые стоят миллионы баксов) и перейти на распределённые горизонтально масштабируемые дешёвые сервера. это выгоднее для фирмы (плюс содержание штата своих профессиональных программистов).
надёжность - это не только софт. но и хард. горизонтальное масштабирование с динамическим распределением нагрузки позволяет продолжать работу, даже если один сервер вообще рухнул, физически. другие сервера возьмут на себя нагрузку. мы рассчитываем нагрузку так, что даже если 2/3 серверов уйдут в даун, то система будет работать. плюс можно плавно добавлять сервера при увеличении числа юзеров. плюс можно разбросать сервера по регионам. в этом и суть. а вот если грохнется один огромный центральный сервер, то заменить его будет небыстро и очень затратно.
Ненене. Чтобы переключить задачу, нужно ее сначала приостановить. Это можно сделаеть или постоянными проверками по всему коду (после чего расходы на сист. вызов покажутся мелочью), или системными способами (о которых я писал). Третьего способа я что-то не вижу.
Да, но для preemption нужен или сигнал (syscall на инициирование) или через тот же ptrace() (сам по себе syscall). для не preemtion и longjmp хватит, это да.
«Под железа закупить» я и имел в виду увеличение количества серверов, Erlang прекрасно горизонтально масштабируется (разницы между отправкой сообщения удаленному или локальному узлу нет вообще).
Чтобы упереться в проблемы производительности надо найти задачку обычно связанную с тяжёлыми вычислениями. Тут уж какой язык кроме низкоуровневых не бери, всё равно будет медленее.
вопрос не в лёгкости написания кода, а в том, что в итоге получится.
Мой опыт показывает, что на си, что на плюсах в итоге получается спагетти из микрооптимизаций, управления памятью и логикой работы. И от этого хрен куда денешься из-за самой низкоуровневой природы этих языков. В эрланге очень многое получается «как бы» скрытым с глаз долой, начиная с управления памятью, заканчивая реализацией многопоточности и диспетчеризацией потоков и только в тех местах где реально необходимо задействуется низкоуровневый код(вдруг надо с помощью SSE какие-то массивы данных молотить). Также из-за функциональной природы языка получается такая штука - у тебя отсутствует изменяемый state, всё общение между процессами идёт сообщениями и это резко снижает количество мьютексов, локов и прочих критических секций до околонулевого уровня, что капитально упрощает отладку, особенно плавающих дедлоков.
Насколько помню, в Erlang'е перехватываются практически все действия потока. Вот пруф:
«Both processes and ports have a „reduction budget“ of 2000 reductions. Any operation in the system costs reductions. This includes function calls in loops, calling built-in-functions (BIFs), garbage collecting heaps of that process[n1], storing/reading from ETS, sending messages (The size of the recipients mailbox counts, large mailboxes are more expensive to send to).»
Возможно, я не настолько Ъ чтобы обсуждать необходимость наличия системы типов в эрланге. Понемногу курю хаскель и мне работать с строгой типизацией нравится, защитное программирование исключается практически полностью, а вызвать не то, не там и не с теми параметрами тебе не даст компилятор.
ну, то есть, плюсы только в лёгкости написания.
мне лично они не совсем понятны, потому что для меня в С++ ничего сложного нет. я совершенно легко и естественно пишу многопоточные приложения. есть методы для стандартной реализации машин состояния, есть циклограммы и т.д. всё это для меня не представляет сложности.
я понимаю, что если речь идёт о среднем программисте с небольшим опытом, то его проще посадить на Java или Erlang. но есть есть время на серьёзную разработку и не жаль ресурсов на найм профессионалов, то можно писать код на С++.
меня-то интересовали принципиальные отличия. скажем так, какие-то языковые конструкции, которые нетипичны для других языков. я понимаю, что сравнивать языки общего назначения с ФЯП некорректно. но всё-таки хотелось понять, в чём их плюсы для разработчика. не то, чтобы я как-то враждебно к ним отношусь. просто пока не вижу достаточных причин для перехода к таким языкам.
Эрланг интерпретирует байткод, поэтому он просто переключает задачу после интерпретации N инструкций.
Ну тут уже паказали, что нет. Но даже если - суть оставалась бы та же - постоянные проверки, «а не пора ли?». Хоть и подход с reductions в целом весьма нетребовательный.
Ага. В то же время в плюсах на critical path часто обходятся без выделений памяти и имеют меньше проблем с производительностью. Тот же эрланг говорит про soft-realtime, но в realtime (в hard - вообще обязательно) за выделение памяти бьют по морде чайником.
меня-то интересовали принципиальные отличия. скажем так, какие-то языковые конструкции, которые нетипичны для других языков. я понимаю, что сравнивать языки общего назначения с ФЯП некорректно. но всё-таки хотелось понять, в чём их плюсы для разработчика. не то, чтобы я как-то враждебно к ним отношусь. просто пока не вижу достаточных причин для перехода к таким языкам.
хыхы! я вообще заметила, что писатели юзерспейса витают в облаках и напрочь игнорируют оптимизацию, будто у них неограниченные ресурсы. видимо, они никогда не писали на ассемблере, а это хорошая практика.
я работала с железяками довольно долго. прошивки, дрова, системы... у меня привычка работать с оглядкой на реальные возможности машины.
чудес-то не бывает и вся виртуализация и интерпретация сжирает ресурсы. в реальной жизни вместо миллиона потоков лучше иметь возможность выбрать в настройках какой-то лимит на количество потоков и крутиться в пуле этих потоков. всё равно интерпретатор делает ту же самую работу: создаёт таски и выполняет их в пуле (хорошо ещё, если в пуле, а не в одном потоке). но на это накладывается интерпретация (пусть даже и после некоторого препроцессинга), что замедляет работу.
Ещё раз, плюсы не только в скорости написания, но и в отладке. Поскольку набор средств для отстреливания себе ног, яиц и прочих важных органов ограничен, то и количество допускаемых ошибок значительно меньше. Может Ъ плюсовики и имеют какие-то хитрые способности находить утечки памяти на глаз или писать строго без утечек, но я, например, так не умею, мне в этом помогает valgrind и другие подобные инструменты. В том же эрланге, например, устроить утечку памяти можно разве что от большого ума. В C++14 всё стало несколько лучше с shared и uniq поинтерами, но я не знаю насколько это будет спасать. Нулевые указатели? Лолшто? это конечно относится к скорости написания, но уменьшение количества защитного кода меня несказанно радует ибо я ленив. Самым замечательным примером в моей практике, на си правда, была функция из менее десятка строк кода логики и около 50 строк защитных проверок. И подобных функций мне пришлось наколбасить пяток примерно. Ну лень мне писать лишний код. В эрланге с использованием patterrn matching и guards количество защитного кода уменьшается до минимального, в хаскелле с строгой системой типов ещё и компилятор на тебя ругнётся в попытке передать в функцию аргумент не подходящий по типу или не пролезающий ни в одно условие pattern matching'а
Суть именно в этом, что с использованием того же эрланга отпадает необходимость писать немалую часть нудных деталей реализации и сосредоточиться на логике работы. А, например, горизонтальное масштабирование(с оговорками) за тебя сделает VM. Не надо писать тонны защитного кода, за тебя его проверит компилятор, по большей части нет необходимости пристально следить за блокировками ибо деструктивного присваивания нет и всё взаимодействие идёт через mailbox(применительно к erlang в многопоточной работе).
Вкалывают роботы, счастлив человек, короче.
Нет, можно конечно гордиться своей илитарностью, что мол я «херачу на плюсах адовый энтерпрайз-продакшен-код», но знать другие инструменты и использовать их для СОБСТВЕННОГО удобства и производительности - как минимум полезно. Я довольно долгое время не врубался как вообще на этом всём можно колбасить что-то рабочее, а потом проникся.
Вот я и говорю, что ты ламер на всю свою тупую башку. Яржал - «юзерспейс» на Оккаме! Негоже столь некомпетентному ламерью рассуждать об оптимизации, смешно получается.
В C++14 всё стало несколько лучше с shared и uniq поинтерами, но я не знаю насколько это будет спасать.
В С++11, раз уж так. И были они в бусте еще очень задолго до того (и я молчу, когда Александреску упомянул их реализацию в книге). А спасают в минимум 99% случаев (кроме идиотов, умудряющихся делать круговые зависимости с shared_ptr). Я давно не видел утечек. А вот дебилов, допускающих разыменования nullptr - куча.
но знать другие инструменты и использовать их для СОБСТВЕННОГО удобства и производительности - как минимум полезно.
по lightweight threads и realtime scheduling я инфы сходу найти не смог, я ведь так понимаю, что разговор про это. Просто вытестение процессов ядром при этом остается.
Да, запамятовал уже что они в C++11 появились. Да, у Александреску было описание и в бусте было, только вот очень многие на них как ложили болт, так до сих пор кладут и буст не используют.
кстати, после беглого прочтения доки на spawn я подумала, что это аналог циклограмм. даже вполне вероятно, что реализация самой машины есть циклограммы в том или ином виде.
мы на С++ писали циклограммы для обработки событий на тракте проверки качества печати: по тракту с огромной скоростью шли банкноты (неважно, могут быть любые объекты) и надо было отслеживать каждую и направлять её в нужное место. причём банкнота проходит сотни датчиков и контрольных точек и весь путь контролируется, а управление механикой направляет банкноту в нужное место. отслеживание всей массы банкнот, параллельно идущих в разных точках по нескольким трактам, проверка данных со всех датчиков, управление железом на огромных скоростях в риалтайме для перенаправления и сортировки - всё это было реализовано на С++, с помощью циклограмм, и работало железобетонно. по сути, циклограммы - это одна из реализаций машины состояний. параллельно обрабатываются события для многих объектов и можно переводить объект в любое состояние (аналог spawn). это просто удобный метод для работы с такими задачами и мы его много где применяли. при этом написание кода не требует какого-то особого мыслительного напряжения.
эх, я постоянно пытаюсь популяризировать буст среди программистов на С++. нечасто это находит отклик :) хотя библиотека просто отличная.
С++11 я тоже люблю, но пока поддержка есть не во всех системах и компиляторах. поэтому тут иногда для совместимости приходится идти на компромисс и юзать буст.
Раз умные товарищи в эрланг типы не запилили, значит они не так уж там нужны.
Не совсем правда.
В Erlang пытались впилить статическую типизацию. Не пошло: язык уже изначально получился слишком динамическим, без кардинальной ломки статику туда не вбить.
Ну hard rt начинается с соответствующей ОС и правильного железа, потому в контексте чистого линукса оно вообще не бывает. А так - rt-thread ОС + rt user-thread'ы с соотв. планированием = success.
ну просто вроде тред про функциональщину с под-тредом про erlang и огранизацию легких процессов, поэтому я надеюсь, что ОС и железо тяжеловесные user-threads не попадают в рамки обсуждения.