F>было бы неплохо, если б скриптовые языки, на которых делают веб-бэкенды, умели общую среду, чтобы не надо было синхронизировать их через какие-то промежуточные технологии. F>а то, что сейчас делают — это стыд какой-то.
жалобы на жизнь
F>и довольно небезопасно. F>при должной медитации можно сделать всё качественно, но работодателей с таким подходом немного. поэтому имеем, что имеем.
снова жалобы на жизнь
программирование — сложно, инструменты — не идеальны, работодатели — охренели, виноват во всем с++, да
BZ>ты как раз успешно указал именно те примеры, которые больше всего нуждаются в зелёных потоках для обработки тысяч одновременных запросов
Как определить что нуждается в зеленых потоках а что нет, есть ли какой-нибудь формальный метод, который позволяет определять, какую пользу потенциально могут принести зеленые потоки проекту?
EL>>С памятью и вводом/выводом я могу эффективнее работать в С или С++, так как я могу там использовать векторный ввод/вывод, mmap, контролировать memory layout объектов и структур данных и тд. Это требует большего количества работы, но зато позволяет достичь лучших результатов.
BZ>использвание асма, simd и gpgpu позволяет долстичь ещё лучших результатов, впорос в том как соотносятся усилия и выигрыш
ровно то же самое можно сказать про любую технологию, даже про зеленые потоки (:
Здравствуйте, Mamut, Вы писали:
M>Понятно, что никто числодробилки на Эрланге писать не будет. Как не будут писать на Руби, Питоне и прочем.
Цимус в том, что на С++ вовсю пишут не просто числодробилки, а параллельные, да еще с кучами "зеленых потоков" прямо на MS PPL, который сам сидит поверх пула потоков, и всё это работает по алгоритму "work stealing". Операция распараллеливание задачи стоит в среднем десятки наносекунд или меньше (операция постановки task в lock-free очередь).
Т.е. фишка в том, что в той нише, где Эрланг был крут (дешевое распараллеливание), появилось мощное конкурирующее нейтивное решение, в котором стоимость распараллеливания (да это просто издевательство какое-то!) примерно равно стоимости операции '+' на Эрланге и намного дешевле операции конкатенации двух строк длиной в один символ на том же Эрланге.
M>У тебя еще есть доверие этому человеку? У меня уже много лет нет.
Это потому что ты много лет сидишь на Эрланге и терпеть не можешь наезды на него. Кароч, это из области психологического, не стоит развивать эту тему. ))
M>А вот у нормальных людей есть доверие как к Эрлангу, так и к его модели, которую стремительно вбирают в себя все, кому не лень.
Ну, модель там простая, в общем-то, и да, наилучшая для современных SMP систем. Теперь такая же модель доступна и для нейтива. Речь может идти только о сравнении алгоритмов дистпетчеризации зеленых потоков поверх пула реальных потоков.
M>ЗЫ. Надо будет пацанам из Ватсаппа рассказать об ущербной модели многопоточности Эрланга, да...
Ну, строго говоря, без специально-заточенной подсистемы ввода-вывода на зеленых потоках далеко не уедешь.
К тому же, алгоритм "work stealing" является наилучшим известным на сегодня для диспетчеризации зеленых потоков. Какой алгоритм диспетчеризации в Эрланге?
Здравствуйте, WolfHound, Вы писали:
WH>Числодробилки это любые вычисления. Если у тебя задача чисто про IO, то на фоне тормозов IO тормоза остального не видно в микроскоп.
Это не совсем так уже относительно давно. "Тормоза IO" приблизились к 2-3-м микросекундам на пакет. Гуглить "onload ethernet" и юзер-мод драйверы к нему. И вот тут уже эффективность диспетчеризации ожидающих данные обработчиков начинает играть заметную рояль.
WH>Но если тебе вдруг нужно будет хоть что-то посчитать, то тебе придётся переходить на другой язык.
Причем, кроме Фортрана и С++ альтернатив на сегодня и нет, если речь об оптимизирующих компиляторах, да еще про вычисления с плавающей точкой.
WH>У меня есть технические аргументы, на которые ты можешь ответить только истерикой, переходом на личности и апелляции к "авторитетам".
Ну, справедливости ради, тебе порой кружит голову очередная обнаруженная универсальность очередного найденного приема/алгорима. ))
Эта "универсальность" — естественное св-во многих математических подходов, разумеется, но не всегда "универсальный" означает "лучший" для конкретного сценария. Собсно, мои споры с тобой зачастую сводились именно к этому. ))
Здравствуйте, BulatZiganshin, Вы писали:
M>>А если говорить именно про Эрланг, то надо еще найти програмистов, которые смогут качественно реализовать эрланговское дерево супервизоров.
BZ>в tbb/ppl есть граф процессов и распространение исключений по нему. тут бы кого-нибудь грамотного кто сравнил эти два подхода...
TBB не использует "зеленые потоки", поэтому сравнивать можно только PPL.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>а чем собственно эти библитоеки занимаются? тот же intel tbb? вот только насчёт зелных потоков меня терзают смутные сомнения — от корутин они отличаются как раз тем что переключение иежду потоками идёт автоматом, и это как я понимаю на С++ не реализуется никем и не планируется ни в каком виде
Не автоматом, а через несколько примитивов-очередей (с разными политиками) в случае PPL. Процедура ожидания данных на этих очередях управляется диспетчером.
Итого, получается простая система: асинхронный ввод-вывод выгребает данные по overlapped и кладёт указатели на заполненные ядром ОС буфера с данными в одну из очередей, где на другой стороне очереди сидит ожидающий данные "зеленый поток" PPL.
BZ>или скаджем node.js — те же асинхронные интерфейсы, добавляем к ним синтаксический сахар и получается вполне аналог эрланга/хаскеля с их зелёными потоками
Скорее jQuery Deferred, но это чуток не то. Это stateless vs statefull корутины. Для коротких цепочек обработчиков пойдёт первый вариант, для развестистого вложенного алгоритма — конечно второй. Но правда в том, что в большинстве асинхронных операций "цепочка" обработчиков получается всего длиной 2-3 узла, а для этого случая stateless-корутины подходят идеально. Поэтому, помимо платформ с "зелеными потоками" в плюсы также добавят stateless корутины: http://rsdn.ru/forum/flame.comp/6066056.1
Здравствуйте, Evgeny.Panasyuk, Вы писали:
V>>Поэтому, помимо платформ с "зелеными потоками" в плюсы также добавят stateless корутины: EP>ЕМНИП, собираются добавить и stackful и stackless — у каждого варианта своих плюсы и минусы, и соответственно применимы в разных контекстах.
ИМХО, для statefull ничего в сам язык добавлять не надо, это запросто реализуется на уровне библиотек.
Здравствуйте, vdimas, Вы писали:
WH>>Но если тебе вдруг нужно будет хоть что-то посчитать, то тебе придётся переходить на другой язык.
V>Причем, кроме Фортрана и С++ альтернатив на сегодня и нет, если речь об оптимизирующих компиляторах, да еще про вычисления с плавающей точкой.
как раз числодробилки хорошо работают с jit, например terra, luajit, julia. а ещё есть бибилотеки, которые используют внутри simd/gpu и простой программист вряд ли так хорошо алгоритм реализует чтобы с ними соревноваться.
вообще, программирование нынешних gpu столь сложно, что у меня есть мысль что наилучшими инструментами работы с ними могут оказаться всяческие хаскели, где высокоуровневый пусть и медлителоьный язык — всё равно язык этот задействован только на уровне генерации gpu-программы
Здравствуйте, vdimas, Вы писали:
V>>>Поэтому, помимо платформ с "зелеными потоками" в плюсы также добавят stateless корутины: EP>>ЕМНИП, собираются добавить и stackful и stackless — у каждого варианта своих плюсы и минусы, и соответственно применимы в разных контекстах. V>ИМХО, для statefull ничего в сам язык добавлять не надо, это запросто реализуется на уровне библиотек.
Да, реализуются, точно также как и обычные потоки. Но в любом случае не помешают.
Впрочем согласен — если бы был выбор что добавить в язык в первую очередь — stateless или stackful — то я бы предпочёл stateless (правда они должны быть правильно сделаны, в некоторых proposal'ах были грубые ошибки). Как раз потому что без изменения языка нормальный stateless не реализовать (только некоторое подобие на макросах).
Здравствуйте, BulatZiganshin, Вы писали:
BZ>вообще, программирование нынешних gpu столь сложно, что у меня есть мысль что наилучшими инструментами работы с ними могут оказаться всяческие хаскели, где высокоуровневый пусть и медлителоьный язык — всё равно язык этот задействован только на уровне генерации gpu-программы
GPU эффективен только для пакетной обработки.
Вот вполне конкретная задача.
Есть звуковой драйвер asio, который с низкими задержками генерирует пакеты данных. Далее эти данные обрабатываются примерно несколькими тысячами "операторов", где в базе у операторов сидит:
— функциональной отображение текущего отсчета (обычно на основе интерполяции через таблицу);
— IIR фильтрация;
— FIR фильтрация, она же свертка, она же корреляция/автокорреляция;
— задержки;
— суммирование/умножение текущих отсчетов сигналов, полученных с разных "веток" алгоритма, в т.ч. через обратную связь.
Цель — добиться задержки звука в тракте не более 5-7ms.
Через GPU не выходит, увы.
С видео проще, т.к. там данные идут в одну сторону, ну и плюс задержка в десятки ms — норма, т.е. даже если частота кадров порядка 100Гц, на самом деле задержка каждого кадра от начала его формирования вовсе не 10ms, т.е. не 1 кадр, а порядка 3-х кадров — по длине конвейера формирования кадров.
Здравствуйте, Ikemefula, Вы писали:
А>>Из чего логически следует, что для этого в С++ либо есть готовая свободная либа, либо эффорт настолько мал, что сторонняя либа не нужна и пишется своими силами. I>Наоборот, задача слишком сложна для ручной реализации.
Возможно. Но уже есть готовые реализации. Дело в их популяризации.
I>Выталкивать, по факту, придется вообще всё. Тот же Эрланг почти ничего не юзает, из системного, АПИ, а то немногое выталкивает в тред-пул. I>Хочешь юзать по максимуму сервисы ОС — добро пожаловать в АДъ
Именно. Нужен контроль над низким уровнем. Ну ты понел. ))
Здравствуйте, Evgeny.Panasyuk, Вы писали:
V>>ИМХО, для statefull ничего в сам язык добавлять не надо, это запросто реализуется на уровне библиотек. EP>Да, реализуются, точно также как и обычные потоки. Но в любом случае не помешают.
Можно пример синтаксиса?
Без претензий на холивар, разве есть большая разница м/у вызовом некоторого зарезервированного ключевого слова
yield;
и использованием некоей библиотечной ф-ии (абстрактно):
coroutine::yield();
?
Тем более, что можно однократно сделать "using coroutine::yield" (или "using namespace coroutine") и использовать просто "yield()"?
EP>Впрочем согласен — если бы был выбор что добавить в язык в первую очередь — stateless или stackful — то я бы предпочёл stateless (правда они должны быть правильно сделаны, в некоторых proposal'ах были грубые ошибки).
Сейчас уже разобрались с "unwrap", заменив его на перегрузку сигнатуры "then" для случая, когда future возвращает другое future (если ты про это).
И ваш покорный слуга как раз реализовал для своей основной работы всю эту кухню для текущих нужд.
Здравствуйте, ELazin, Вы писали:
EL>снова жалобы на жизнь EL>программирование — сложно, инструменты — не идеальны, работодатели — охренели, виноват во всем с++, да
сказочная глупость.
неудивительно, что шеридан с тобой согласен
Здравствуйте, BulatZiganshin, Вы писали:
BZ>т.е. преимущество эрланга в том, что там прибито гвоздями то, что в C++ ревлизуется несколькими опенсорсными бибилотками на выбор? или это его недостаток?
эрланг — это фреймворк с dsl.
странно реализацию фичи называть недостатком.
F>сказочная глупость. F>неудивительно, что шеридан с тобой согласен
Почему сразу глупость? сначала ты пожаловался на то, что рантайм у динамических языков говно, потом на то что делать хорошо на с++ сложно и работодатели не хотят, предполагалось что мы об этом поговорим и я посочувствую или что?
Здравствуйте, Sinclair, Вы писали:
S>А что у нас с IOCP?
boost::asio
Вообще, тут надо не IOCP рассматривать, а сравнивать схему reactor vs proactor. Потому что конкретно IOCP не при чем от слова совсем, он позволяет реализовать как reactor, так и proactor, убив в первом случае весь цимус ядерного ввода-вывода прямо в юзверские буфера.
Например, аналог IOCP реализуется как в винде так и в posix-системах через прослушку на UDP-сокете в БЛОКИРУЮЩЕМ режиме одновременно нескольких потоков — именно так работает протокол IAX, являющийся на сегодня наиболее эффективным в плане диспетчеризации VoIP.
Т.е. просто куча потоков сидит себе на UDP-сокете, и по мере прихода новых пакетов просыпается очередной поток. В Linux при этом можно управлять шедуллингом потоков, в т.ч. достичь алгоритма, близкого по логике к популярному ныне work stealing.
Аналогично можно сделать на eventfd в Linux или pipe, точно так же на ЛЮБОМ файле (в т.ч. mmap или named pipe) в виндах тоже. Т.е. получаем идентичную IOCP схему без IOCP.
Т.е. схема всегда одна — это несколько предварительно созданных потоков, которые ожидают одну очередь в блокирующем режиме. А отличие reactor vs proactor в том, по какому событию мы просыпаемся — по событию готовности данных для последующего чтения или по событию уже завершенного чтения в буфер. Показанная мно схема — это последний вариант, т.е. наиболее эффективный. Дополнительно можно это дело оптимизировать — если в linux или винде указать сокету размер внутреннего буфера для чтения 0, то ядро будет читать прямо в поданный указатель на юзверский буфер.
S>Есть ли в бусте что-то, позволяющее мне нарезать линейный (по спецификации) алгоритм на фрагменты, которые можно исполнять по мере поступления IOCP, без мучительной отладки и замусоривания кода бойлерплейтом?
(В С++ std::future<> — это аналог дотнетного Task<>, с той разницей, что Task<> обязательно инкапсулирует в себе некую лямбду (делегат), а future — это независимый механизм сигналинга, где хендл для этого сигналинга представлен отдельным объектом — promise<>).
Т.е. дотнетный Task это что-то вроде плюсового (грубо):
future<int> async(auto lambda, auto scheduler)
{
promise<int> p;
auto f = p.get_future();
auto wrappedLambda = []() {
try {
promise.set_value(lambda());
} catch(...) {
promise.set_exception(current_exception());
}
};
scheduler.schedule(wrappedLambda);
return f;
}
Дальнейшая связь идёт "вручную", как если бы в дотнете вместо await расписывали бы вручную Task.ContinueWith(nextLambda). В C# этой росписью занимается компилятор, по ссылкам аналогичный proposal для следующего стандарта C++.
Но справделивости ради, расписывать вручную задачи иногда тоже имеет смысл, т.е. это надо уметь, т.е. руку тоже надо "набивать". ))
Например, ситуации Task.WhenAll/Task.WhenAny нужно кодить ручками и только ручками.
Здравствуйте, vdimas, Вы писали:
V>>>ИМХО, для statefull ничего в сам язык добавлять не надо, это запросто реализуется на уровне библиотек. EP>>Да, реализуются, точно также как и обычные потоки. Но в любом случае не помешают. V>Можно пример синтаксиса?
Чего? Stateful coroutine? — Boost.Coroutine.
V>Без претензий на холивар, разве есть большая разница м/у вызовом некоторого зарезервированного ключевого слова V>
V>yield;
V>
V>и использованием некоей библиотечной ф-ии (абстрактно): V>
V>coroutine::yield();
V>
V>? V>Тем более, что можно однократно сделать "using coroutine::yield" (или "using namespace coroutine") и использовать просто "yield()"?
А я не говорил что есть разница. Я как раз наоборот показываю пример что обычные потоки в C++ реализовывались в чисто библиотечном виде — например boost::thread, который практически полностью перекочевал в ISO.
Точно также факт того что stackful coroutine реализуется в виде библиотеки, не является аргументом против включения их в стандарт (в таком же библиотечном виде, без дополнительных ключевых слов).
EP>>Впрочем согласен — если бы был выбор что добавить в язык в первую очередь — stateless или stackful — то я бы предпочёл stateless (правда они должны быть правильно сделаны, в некоторых proposal'ах были грубые ошибки). V>Сейчас уже разобрались с "unwrap", заменив его на перегрузку сигнатуры "then" для случая, когда future возвращает другое future (если ты про это).
Одна из проблем была в том, что предлагалось каждую stackless корутину аллоцировать в куче. Я же считаю что аллокация должна быть ортогональна — задача компилятора сгенерировать класс конечный автомат из моего "линейного" кода с yield, а уж где я его буду размещать — в куче, на стэке, в каком-нибудь векторе — это моя забота. Также хочется чтобы такой класс конечный автомат поддерживал и копирование и перемещение, а в предложениях ЕМНИП он был прибит гвоздями к тому месту где был создан.
Другой проблемой было то, что первоначально предложенные корутины (насколько я помню, они даже были реализованы как расширение MSVC) — вобрали в себя всё худшее от stackless и stackful, и убрав преимущества. Использование было как у stackless (то есть нельзя сделать yield через несколько уровней), а вот реализация была как у stackful (то есть относительно громоздкие, в десятки байт их без большого труда не поместить).
Здравствуйте, vdimas, Вы писали:
S>>Есть ли в бусте что-то, позволяющее мне нарезать линейный (по спецификации) алгоритм на фрагменты, которые можно исполнять по мере поступления IOCP, без мучительной отладки и замусоривания кода бойлерплейтом? V>Нет.
Как это нет? В Boost.Asio есть поддержка stackful coroutine из коробки.