Расскажите про coroutines и их реализации для C/C++; надо провести сравнение



Приветствую!А похвалите/наговорите гадостей про coroutines и их реализации для C/C++; надо провести сравнение.Спасибо!
1035   32  

Comments

  1. Альберт Галимов
    Альберт Галимов 5 лет назад
    Юзал boost::asio с ее интеграцией к boost::coroutines. Теперь ярый фанат, т.к. штука решает целые пласты проблем разом. Из минусов - старт корутины довольно тяжел и потом контекст многовато памяти ест, но тут тоже есть обходные пути
  2. Andrey Shetukhin
    Andrey Shetukhin 5 лет назад
    >старт корутины довольно тяжел
    • Альберт Галимов
      Альберт Галимов 5 лет назад
      Старт тяжел изза того что нужно создать контекст, выделить стэк итд. Тут есть сравнение http://www.boost.org/.../doc/html/coroutine/performance.html Если кратко то свитч корутины в 1000 раз быстрее, чем старт новой. По памяти у меня вышло корутины boost::asio едят по 32кб каждая. В принципе оба момента можно легко обойти написав пул корутин, куда потом постить джобы.
  3. Iurii Krasnoshchok
    Iurii Krasnoshchok 5 лет назад
    Самая большая проблема в том, что без поддержки рантайма нет автоматического управления памятью. Приходится либо выделать среднюю по больнице для всех короутин, либо ресайзить вручную в процессе работы. Получается, что для обслуживания 100к подключений уходит 100-250Mb (в зависимости от нужд стека).Базово можно взять boost::context - очень правильная и минималистичная реализация (я там немного помогал автору). boost::coroutine сделан поверх тем же человеком, но мне не подошел интерфейс, я делал свой.
    • Andrey Shetukhin
      Andrey Shetukhin 5 лет назад
      >Получается, что для обслуживания 100к подключений уходит 100-250Mb
    • Iurii Krasnoshchok
      Iurii Krasnoshchok 5 лет назад
      Если стек у короутины 32к, то это уже 3Gb на 100к.В общем, мне даже вариант с 250Mb не подошел, но это моя боль.
    • Evgeny Zajcev
      Evgeny Zajcev 5 лет назад
      Iurii Krasnoshchok чувак, ты чутка путаешь виртуальную память с физической. Допустим у тебя стек на 100мб и 100к корутин, тогда виртуальной памяти ты запользуешь в районе 10Тб, что просто тьфу для x64. И допустим ты так крутанско код оформил (со штуками типа zero-copy, data replication, и тд), что тебе для обслуживания клиента только 60 байт на стеке надо, тогда суммарный юзаж физической памяти у тебя будет 6Mb
    • Iurii Krasnoshchok
      Iurii Krasnoshchok 5 лет назад
      Evgeny Zajcev Еще раз: память мы выделяем явно - malloc / whatever. На Linux это будет виртуальная память до первого page fault (на котором мы получим страницу), на Windows это будет виртуальная память, под которую отмаплена физическая.
  4. Iurii Krasnoshchok
    Iurii Krasnoshchok 5 лет назад
    Вторая проблема - это кривые либы. Если либа внутри хватает мьютекс на каком-то call и держит до другого call, то можно словить deadlock на попытке взять тот же мьютекс.
    • Andrey Shetukhin
      Andrey Shetukhin 5 лет назад
      Пример можно?
    • Iurii Krasnoshchok
      Iurii Krasnoshchok 5 лет назад
      Я боюсь соврать, но по-моему этим грешила libxml2.
    • Ильнар Борханов
      Ильнар Борханов 5 лет назад
      Andrey Shetukhin одна корутина схватила лок, переключилась на другую, вторая в дедлок при попытки схватить лок.
    • Andrey Shetukhin
      Andrey Shetukhin 5 лет назад
      >одна корутина схватила лок,
    • Ilya Golshtein
      Ilya Golshtein 5 лет назад
      Такого рода проблемы были актуальны лет десять назад, когда N тредов с точки зрения прикладного программиста на самом деле представляли собой M потоков исполнения операционной системы и этим нельзя была управлять.В случае корутин это _не_ проблема, это абсолютно нормальный ход вещей, который нужно понимать.
  5. Iurii Krasnoshchok
    Iurii Krasnoshchok 5 лет назад
    Я сейчас думаю зайти с другой стороны: подключить С++ библиотеку в golang, а там уже рулить goroutines. Пока времени не хватает попробовать.
    • Ильнар Борханов
      Ильнар Борханов 5 лет назад
      интересно
    • Evgeny Zajcev
      Evgeny Zajcev 5 лет назад
      Не хочешь сначала libmill попробовать?
    • Iurii Krasnoshchok
      Iurii Krasnoshchok 5 лет назад
      Evgeny Zajcev Я не хочу coroutines без поддержки рантайма, я выше написал почему.
    • Evgeny Zajcev
      Evgeny Zajcev 5 лет назад
      Iurii Krasnoshchok а в чём проблема больших стеков для корутин? Это же виртуальная память - просто адреса. Физическая память будет расходоваться ровно столько, насколько глубоко зайдёшь в стек
    • Iurii Krasnoshchok
      Iurii Krasnoshchok 5 лет назад
      Evgeny Zajcev Это утверждение не работает в Windows, где нужно работать только с явно отмапленной (commited) памятью. Конкретно в моем случае короутины выходили довольно прожорливые (~16к на стек), потому я переписал все на lambda, код тоже простой, но памяти расходуется намного меньше.Основной поинт в go - это не goroutines, а channels - готовые примитивы для написания кода в стиле CSP (или Actor) model.
    • Evgeny Zajcev
      Evgeny Zajcev 5 лет назад
      Iurii Krasnoshchok ну проблема получается в кривой реализации vm, а не в корутинах. Тут тогда надо скорость и удобство откладывать в сторонку
    • Evgeny Zajcev
      Evgeny Zajcev 5 лет назад
      Iurii Krasnoshchok в libmill есть channels
    • Iurii Krasnoshchok
      Iurii Krasnoshchok 5 лет назад
      Evgeny Zajcev Вот здесь появляется следующая проблема: если есть channel, и мы гоняем сложную структуру, то кто ей владеет, и кто должен удалять, как не поймать race, когда структура бегает по указателю? И как не фрагментировать память на аллокации таких структур.Я все это проходил. Я больше не хочу ручками, я хочу garbage collector и не включать мозги.У меня все равно 90% обработки запроса проходит в syscall на TCP/IP.
    • Evgeny Zajcev
      Evgeny Zajcev 5 лет назад
      Iurii Krasnoshchok тогда зачем С?
    • Evgeny Zajcev
      Evgeny Zajcev 5 лет назад
      Evgeny Zajcev а, или ты говоришь из go вызывать С, а не наоборот.. Тогда, конечно норм
    • Iurii Krasnoshchok
      Iurii Krasnoshchok 5 лет назад
      Evgeny Zajcev Я очень плотно работаю с памятью. Cachelot - это LRU, который живет в фиксированном объеме
  6. Andrei Nigmatulin
    Andrei Nigmatulin 5 лет назад
    Юзаем давно, под нагрузкой, bare makecontext/swapcontext calls + слой связки с event loop. Впечатления положительные, устранили неопрятный callback hell. Из граблей, что словили - в начале стека нужно обязательно ставить guard page с PROT_NONE, т.к. сторонние библиотеки могут жрать стек непредсказуемо много (jemalloc был у нас).
  7. Анатолий Орлов
    Анатолий Орлов 5 лет назад
    В яндексе довольно много на них написано включая balancer, раздачу запросов на базовые поиски и spider который интернет качает, яндексная реализация лежит в open source на github.
  8. Макс Лапшин
    Макс Лапшин 5 лет назад
    я тебе более того расскажу:
  9. Григорий Соколик
    Григорий Соколик 5 лет назад
    Подписываюсь.
  10. Iurii Krasnoshchok
    Iurii Krasnoshchok 5 лет назад
    Кстати, на посмотреть. Есть панковская libcppa. У них есть абсолютно волшебный концепт - atom (слизано с Erlang): мы превращаем lower case alphabet в int64, с помощью 6bit encoding в compile-time. По atom можно делать switch, выходит как pattern matching.https://github.com/actor-framework/actor-framework
  11. Анатолий Орлов
    Анатолий Орлов 5 лет назад
    У яндекса в github лежит balancer, который написан на своих корутинах, которые всем нравятся и много где внутри используются.