LINUX.ORG.RU

Ответ на: комментарий от anonymous

У тебя потоки только в syscall-ах будут переключаться

4.2.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от Pavval

Сигнал прерывает ядерный тред

То есть все userspace треды в итоге будут мапиться только на один физический? Спасибо, не надо.
+ Как будете переключать стек/регистры без оверхеда на системные вызовы?

rand
()
Ответ на: комментарий от Iron_Bug

Конечно, подобный софт можно написать хоть на brainfuck'e если позволяет опыт и аккрутаность. Но дело вот в чем: на С++ создание безотказного приложения - это гемор тот еще, а на Erlang'e это все «из коробки» и никакого «защитного» программирования нет. Имхо, фирме дешевле железа докупить, чем оплачивать работу высококвалифицированного программиста. Так что пусть Erlang медленнее, но масштабируемость + скорость разработки решает.

NegatiV
()
Ответ на: комментарий от rand

То есть все userspace треды в итоге будут мапиться только на один физический?

Да нет, что мешает мигрировать на другие kernel/hardware потоки при необходимости?

+ Как будете переключать стек/регистры без оверхеда на системные вызовы?

Опп, это да. А как эрланг это делает?

Pavval ★★★★★
() автор топика
Последнее исправление: Pavval (всего исправлений: 1)
Ответ на: комментарий от anonymous

просто не обязательно плодить столько потоков. это ошибка в проектировании или лень программистов.
например, если пул тасков и их можно обрабатывать в сотне потоков. эффективность будет выше. это стандартное решение для обработки множества коннектов.

Iron_Bug ★★★★★
()

Не написал, но являюсь соавтором нескольких erlang-овых проектов. Сбор и парсинг Netflow, свертки полученных данных. СМС-гейт. SCADA. Все это сугубо телекомовские задачи, язык очень хорошо ложится на их специфику.

outtaspace ★★★
()
Ответ на: комментарий от Pavval

+ Как будете переключать стек/регистры без оверхеда на системные вызовы?

Опп, это да.

А в чем проблема? longjmp, условно говоря.

tailgunner ★★★★★
()
Ответ на: комментарий от NegatiV

насчёт «дешевле железа закупить» не соглашусь. наш отдел разработки создан именно с целью избавиться от мейнфреймов (которые стоят миллионы баксов) и перейти на распределённые горизонтально масштабируемые дешёвые сервера. это выгоднее для фирмы (плюс содержание штата своих профессиональных программистов).
надёжность - это не только софт. но и хард. горизонтальное масштабирование с динамическим распределением нагрузки позволяет продолжать работу, даже если один сервер вообще рухнул, физически. другие сервера возьмут на себя нагрузку. мы рассчитываем нагрузку так, что даже если 2/3 серверов уйдут в даун, то система будет работать. плюс можно плавно добавлять сервера при увеличении числа юзеров. плюс можно разбросать сервера по регионам. в этом и суть. а вот если грохнется один огромный центральный сервер, то заменить его будет небыстро и очень затратно.

Iron_Bug ★★★★★
()
Ответ на: комментарий от NegatiV

Ненене. Чтобы переключить задачу, нужно ее сначала приостановить. Это можно сделаеть или постоянными проверками по всему коду (после чего расходы на сист. вызов покажутся мелочью), или системными способами (о которых я писал). Третьего способа я что-то не вижу.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Да, но для preemption нужен или сигнал (syscall на инициирование) или через тот же ptrace() (сам по себе syscall). для не preemtion и longjmp хватит, это да.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от Iron_Bug

«Под железа закупить» я и имел в виду увеличение количества серверов, Erlang прекрасно горизонтально масштабируется (разницы между отправкой сообщения удаленному или локальному узлу нет вообще).

NegatiV
()
Ответ на: комментарий от NegatiV

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

Iron_Bug ★★★★★
()
Ответ на: комментарий от Iron_Bug

Чтобы упереться в проблемы производительности надо найти задачку обычно связанную с тяжёлыми вычислениями. Тут уж какой язык кроме низкоуровневых не бери, всё равно будет медленее.

вопрос не в лёгкости написания кода, а в том, что в итоге получится.

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

Dark_SavanT ★★★★★
()
Ответ на: комментарий от Iron_Bug

Ты ламер, и не понимаешь модели erlang-а. C++ головного мозга, не лечится.

Еще программистам на Occam попробуй затереть про «не надо плодить столько процессов».

Давно убедился, что приплюснутые вообще органически не способны понимать concurrency.

anonymous
()
Ответ на: комментарий от Pavval

Да, но для preemption нужен или сигнал (syscall на инициирование) или через тот же ptrace()

Для вытеснения вычислительной нити - да, но для вытеснения по началу В/В - нет. И сама вычислительная модель Erlang заточена для массированного В/В.

tailgunner ★★★★★
()
Ответ на: комментарий от Dark_SavanT

Раз умные товарищи в эрланг типы не запилили, значит они не так уж там нужны.

Эти товарищи в других вещах умные. Кроме того, Erlang - язык старый, в те времена важность системы типов просто не понимали.

tailgunner ★★★★★
()
Ответ на: комментарий от Pavval

Насколько помню, в 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).»

Т.е. есть только проверка на reductions < 2000.

NegatiV
()
Ответ на: комментарий от tailgunner

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

Dark_SavanT ★★★★★
()
Ответ на: комментарий от Pavval

Третьего способа я что-то не вижу

Эрланг интерпретирует байткод, поэтому он просто переключает задачу после интерпретации N инструкций.

rand
()
Ответ на: комментарий от Dark_SavanT

ну, то есть, плюсы только в лёгкости написания.
мне лично они не совсем понятны, потому что для меня в С++ ничего сложного нет. я совершенно легко и естественно пишу многопоточные приложения. есть методы для стандартной реализации машин состояния, есть циклограммы и т.д. всё это для меня не представляет сложности.
я понимаю, что если речь идёт о среднем программисте с небольшим опытом, то его проще посадить на Java или Erlang. но есть есть время на серьёзную разработку и не жаль ресурсов на найм профессионалов, то можно писать код на С++.

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

Iron_Bug ★★★★★
()
Ответ на: комментарий от rand

Эрланг интерпретирует байткод, поэтому он просто переключает задачу после интерпретации N инструкций.

Ну тут уже паказали, что нет. Но даже если - суть оставалась бы та же - постоянные проверки, «а не пора ли?». Хоть и подход с reductions в целом весьма нетребовательный.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от Pavval

можно не по всему коду, а в местах, где это безопасно, например при выделении памяти под объекты (так напр. это сделано в RTS haskell).

qnikst ★★★★★
()
Ответ на: комментарий от Iron_Bug

Для начала надо эти языки хотя бы понимать, прежде чем рассуждать.

anonymous
()
Ответ на: комментарий от Iron_Bug

я понимаю, что сравнивать языки общего назначения с ФЯП некорректно

Сравнивать ортогональные характеристики действительно некорректно.

korvin_ ★★★★★
()
Ответ на: комментарий от qnikst

Ага. В то же время в плюсах на critical path часто обходятся без выделений памяти и имеют меньше проблем с производительностью. Тот же эрланг говорит про soft-realtime, но в realtime (в hard - вообще обязательно) за выделение памяти бьют по морде чайником.

Pavval ★★★★★
() автор топика
Последнее исправление: Pavval (всего исправлений: 1)
Ответ на: комментарий от Iron_Bug

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

1. spawn

2. Pid ! {self(), .... }

NegatiV
()
Последнее исправление: NegatiV (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

Iron_Bug ★★★★★
()
Ответ на: комментарий от NegatiV

хорошо. почитаю про это на досуге. пока не могу сказать ничего, ибо просто не знаю, что это за фичи.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Iron_Bug

Ещё раз, плюсы не только в скорости написания, но и в отладке. Поскольку набор средств для отстреливания себе ног, яиц и прочих важных органов ограничен, то и количество допускаемых ошибок значительно меньше. Может Ъ плюсовики и имеют какие-то хитрые способности находить утечки памяти на глаз или писать строго без утечек, но я, например, так не умею, мне в этом помогает valgrind и другие подобные инструменты. В том же эрланге, например, устроить утечку памяти можно разве что от большого ума. В C++14 всё стало несколько лучше с shared и uniq поинтерами, но я не знаю насколько это будет спасать. Нулевые указатели? Лолшто? это конечно относится к скорости написания, но уменьшение количества защитного кода меня несказанно радует ибо я ленив. Самым замечательным примером в моей практике, на си правда, была функция из менее десятка строк кода логики и около 50 строк защитных проверок. И подобных функций мне пришлось наколбасить пяток примерно. Ну лень мне писать лишний код. В эрланге с использованием patterrn matching и guards количество защитного кода уменьшается до минимального, в хаскелле с строгой системой типов ещё и компилятор на тебя ругнётся в попытке передать в функцию аргумент не подходящий по типу или не пролезающий ни в одно условие pattern matching'а

Суть именно в этом, что с использованием того же эрланга отпадает необходимость писать немалую часть нудных деталей реализации и сосредоточиться на логике работы. А, например, горизонтальное масштабирование(с оговорками) за тебя сделает VM. Не надо писать тонны защитного кода, за тебя его проверит компилятор, по большей части нет необходимости пристально следить за блокировками ибо деструктивного присваивания нет и всё взаимодействие идёт через mailbox(применительно к erlang в многопоточной работе).

Вкалывают роботы, счастлив человек, короче.

Нет, можно конечно гордиться своей илитарностью, что мол я «херачу на плюсах адовый энтерпрайз-продакшен-код», но знать другие инструменты и использовать их для СОБСТВЕННОГО удобства и производительности - как минимум полезно. Я довольно долгое время не врубался как вообще на этом всём можно колбасить что-то рабочее, а потом проникся.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от Iron_Bug

Вот я и говорю, что ты ламер на всю свою тупую башку. Яржал - «юзерспейс» на Оккаме! Негоже столь некомпетентному ламерью рассуждать об оптимизации, смешно получается.

anonymous
()
Ответ на: комментарий от Dark_SavanT

В C++14 всё стало несколько лучше с shared и uniq поинтерами, но я не знаю насколько это будет спасать.

В С++11, раз уж так. И были они в бусте еще очень задолго до того (и я молчу, когда Александреску упомянул их реализацию в книге). А спасают в минимум 99% случаев (кроме идиотов, умудряющихся делать круговые зависимости с shared_ptr). Я давно не видел утечек. А вот дебилов, допускающих разыменования nullptr - куча.

но знать другие инструменты и использовать их для СОБСТВЕННОГО удобства и производительности - как минимум полезно.

Я бы сказал это _обязательно_.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от Dark_SavanT

Будет. Особый уличный. Для вызова перед стартом задачи, чтобы раз и навсегда выделить память.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от Pavval

по lightweight threads и realtime scheduling я инфы сходу найти не смог, я ведь так понимаю, что разговор про это. Просто вытестение процессов ядром при этом остается.

qnikst ★★★★★
()
Ответ на: комментарий от Pavval

Да, запамятовал уже что они в C++11 появились. Да, у Александреску было описание и в бусте было, только вот очень многие на них как ложили болт, так до сих пор кладут и буст не используют.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от Pavval

Это уже не совсем маллок, это выделение статического буфера перед работой, а там уже крутись как хочешь, fortran-style :)

Dark_SavanT ★★★★★
()
Ответ на: комментарий от NegatiV

кстати, после беглого прочтения доки на spawn я подумала, что это аналог циклограмм. даже вполне вероятно, что реализация самой машины есть циклограммы в том или ином виде.
мы на С++ писали циклограммы для обработки событий на тракте проверки качества печати: по тракту с огромной скоростью шли банкноты (неважно, могут быть любые объекты) и надо было отслеживать каждую и направлять её в нужное место. причём банкнота проходит сотни датчиков и контрольных точек и весь путь контролируется, а управление механикой направляет банкноту в нужное место. отслеживание всей массы банкнот, параллельно идущих в разных точках по нескольким трактам, проверка данных со всех датчиков, управление железом на огромных скоростях в риалтайме для перенаправления и сортировки - всё это было реализовано на С++, с помощью циклограмм, и работало железобетонно.
по сути, циклограммы - это одна из реализаций машины состояний. параллельно обрабатываются события для многих объектов и можно переводить объект в любое состояние (аналог spawn). это просто удобный метод для работы с такими задачами и мы его много где применяли. при этом написание кода не требует какого-то особого мыслительного напряжения.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Dark_SavanT

эх, я постоянно пытаюсь популяризировать буст среди программистов на С++. нечасто это находит отклик :) хотя библиотека просто отличная.
С++11 я тоже люблю, но пока поддержка есть не во всех системах и компиляторах. поэтому тут иногда для совместимости приходится идти на компромисс и юзать буст.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Dark_SavanT

Раз умные товарищи в эрланг типы не запилили, значит они не так уж там нужны.

Не совсем правда.

В Erlang пытались впилить статическую типизацию. Не пошло: язык уже изначально получился слишком динамическим, без кардинальной ломки статику туда не вбить.

Miguel ★★★★★
()
Ответ на: комментарий от Dark_SavanT

Это уже не совсем маллок, это выделение статического буфера перед работой, а там уже крутись как хочешь, fortran-style :)

Я что-то не припомню, чтобы для итерации rt-задачи нужно было работать с кучей, т.е. иметь не заранее четко определенный объем данных.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от qnikst

Ну hard rt начинается с соответствующей ОС и правильного железа, потому в контексте чистого линукса оно вообще не бывает. А так - rt-thread ОС + rt user-thread'ы с соотв. планированием = success.

Pavval ★★★★★
() автор топика
Ответ на: комментарий от Pavval

ну просто вроде тред про функциональщину с под-тредом про erlang и огранизацию легких процессов, поэтому я надеюсь, что ОС и железо тяжеловесные user-threads не попадают в рамки обсуждения.

qnikst ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.