Re[6]: C++20 coroutines (co_await)
От: reversecode google
Дата: 07.01.21 11:48
Оценка: :))) :))) :)
предлагаю всех кто чего то не осилил в С++ называть — тёмками

так сказать, увековечить первого не осилившего героя на века
Re[3]: C++20 coroutines (co_await)
От: reversecode google
Дата: 06.01.21 23:29
Оценка: +1 :))) :))
можно и так сказать
только сделали сильно круче чем в расте или других языках
очень огромные возможности для кастомизации
  музыченко не читать
даже в ядре можно поюзать если хочеться
Re: C++20 coroutines (co_await)
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.01.21 12:47
Оценка: 1 (1) +4
Здравствуйте, okman, Вы писали:

O>корутины.


Отчего эта корявая калька так расплодилась в народе? Есть же (еще с середины прошлого века) отличный термин — сопрограммы. Прям тест на знание истории программирования.
Re: C++20 coroutines (co_await)
От: х Россия  
Дата: 09.01.21 05:22
Оценка: 53 (4)
Здравствуйте, okman, Вы писали:

O>Всем привет!


O>Изучаю C++20. В целом все понятно, но одна вещь вызывает наибольшие затруднения — корутины.


Всё просто, если немного упростить с деталями:
реализуешь шаблон coroutine_traits с внутренней структурой promise_type — это объект который будет использоваться в функции использующей корутины для управления работой.

По сути функция
T f(T1 a1, T2 a2 ...) {

   co_await ...
   co_return ...
}


преобразуется в:
T f(T1 a1, T2 a2 ...) {
struct Arguments {
  coroutine_traits<T, T1, T2...>::promise_type this_corutine;
  T1 a1;
  T2 a2;
};
  Arguments args { coroutine_traits::promise_type, std::move(a1), std::move(a2) ... };
  ...
  return args->this_corutine.get_return_object();
}


То есть при первом же вызове оператора корутин формируется структура для работы с ними.


Далее когда есть вызов:
auto res = co_await fnested(...);


и пусть при этом
TResult fnested(...)


тогда co_await преобразуется в (понятно, что move расставлены не корректно, но они для демонстрации передачи владением объекта в другой код)
  auto fnested_awaiter = operator co_await(fnested(...));

  auto rest_code = [std::move(fnested_awaiter), std::move(args)]() {
      auto res = fnested_awaiter.await_resume();
      ...//Rest code
  };

  if(!fnested_awaiter.await_ready()){
    //Suspend
    fnested_awaiter.await_suspend(std::move(rest_code));
  } else {
    rest_code();
  }


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

co_return ещё проще — он просто вызывает метод return_value для вашего promise_type.

Таким образом
T f(T1 a1, T2 a2 ...) {

   auto res = co_await fnested(...);
   co_return ...;
}


преобразуется в что-то вида:
T f(T1 a1, T2 a2 ...) {
 struct Arguments {
  coroutine_traits<T, T1, T2...>::promise_type this_corutine;
  T1 a1;
  T2 a2;
 };
 Arguments args { coroutine_traits::promise_type, std::move(a1), std::move(a2) ... };
 
 auto fnested_awaiter = operator co_await(fnested(...));
 auto rest_code = [std::move(fnested_awaiter), std::move(args)]() {
      auto res = fnested_awaiter.await_resume();
      args->this_corutine.return_value(...);//co_return ...;
  };
 if(!fnested_awaiter.await_ready()){
  //Suspend
  fnested_awaiter.await_suspend(std::move(rest_code));
 } else {
  rest_code();
 }
 return args->this_corutine.get_return_object();
}


Собственно всё. Дальше Вы сами решаете как строить цепочки функций, как производить "просыпание" и т.п. В этом мощь. В отличии от C# вы тут можете выбирать ту модель которую считаете оптимальной.

Более детально можно посмотреть реализацию тут.
С уважением Вадим.
Отредактировано 09.01.2021 6:49 х . Предыдущая версия . Еще …
Отредактировано 09.01.2021 6:48 х . Предыдущая версия .
Отредактировано 09.01.2021 5:24 х . Предыдущая версия .
Re[3]: C++20 coroutines (co_await)
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.01.21 17:17
Оценка: +3
Здравствуйте, rg45, Вы писали:

R>Странно, что тебя совершенно не смущает, что слово калька также является заимствованным из иностранного языка. Как и слово "программа", кстати.


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

А "корутина" — столь же тупое передирание иностранного слова в кириллицу, сколь и "менеджмент", "супервайзинг" и подобное. В оборот их вводят те, кто толком не знает родного языка, а распространяют те, кто этого языка не уважает.
Re[19]: C++20 coroutines (co_await)
От: х Россия  
Дата: 17.01.21 13:54
Оценка: :)))
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ты судя по-всему, осведомлён только об одном каком-то специфичном use-case'е, близком к твоей прикладной области, и проецируешь частные требования на все корутины, что никак недопустимо говоря о языке с таким широким применением как C++

EP>Твоё предложение использовать шаблоны и лямбды вместо корутин — абсурдно, ибо означает "нарезай код на продолжения вручную" и проблему распутывания кода никак не решает, а по сути отрицает

EP>В целом даже непонятно с чем ты споришь, ибо возвможность доступа к конкретному типы корутины была бы крайне полезна для одних use-case'ов, и не мешала бы остальным, так как при необходимости тип элементарно стирается. win-win. Хочешь слепо защищать авторов этого конкретного proposal — ну удачи


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

Делать предположения обо мне довольно глупо. Я вижу твою тягу к нравоучениям, но так же вижу, что в плюсах ты плаваешь, так как ты допускаешь высказывания в тексте, которые ни один профи ни делает. Я ж не тыкаю тебя носом в это (твою не опытность). Зачем ты пробуешь принизить собеседника?

Ладно — я больше отвечать не буду. Если будет что-то по существу пиши. Если снова чешется чему-то меня научить, лучше найти другого слушателя.
С уважением Вадим.
Re: C++20 coroutines (co_await)
От: flаt  
Дата: 07.01.21 11:07
Оценка: 17 (2)
Здравствуйте, okman, Вы писали:



O>Пробовал вникать в примеры на en.cppreference.com, смотрел как устроены асинхронные вызовы в C++/WinRT, был на Хабре,

O>на MSDN, на MSVC Team Blog, смотрел исходники библиотеки cppcoro, но ясности не прибавилось.

Можно ещё посмотреть выступления их автора, Гора Нишанова: https://www.youtube.com/results?search_query=gor+nishanov+coroutines

Но вообще, тоже подпишусь в надежде на достойную доку.
Re: C++20 coroutines (co_await)
От: reversecode google
Дата: 06.01.21 20:54
Оценка: 14 (2)
если и это не поймете, значит оно не для вас

корутины
Re[6]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 14:44
Оценка: 5 (2)
Здравствуйте, landerhigh, Вы писали:

L>Не уверен насчет крутости. Пока сам не использовал всерьез, лишь игрался невсерьез.

L>-Они stackless. Значит, yield'ануть из глубин вложенных вызовов функций не выйдет.
L>+Они stackelss. Значит, оверхед по памяти ограничен и оверхед на переключение контекста должен быть минимальным
L>Этот плюс, имхо, должен перекрывать минус на порядок.

И stackless и stackful хороши по-своему.
Stackful легко реализуются в виде библиотеки — см Boost.Coroutine. А вот stackless в виде библиотеки не очень, и не полноценно — смотри реализацию в Boost.Asio. Поэтому вполне логично добавить stackless в стандарт в первую очередь.

Другое дело что походу то что завезли в стандарт, оно не самое лучше из того что можно было сделать, а конкртено в том месте где они впипдюрили аллоцирование фрейма, которого могло бы не быть, и что открыло бы ещё больше zero-overhead вариантов использования. В частности даже stackless макро-реализация из Boost.Asio обошлась без аллокаций, и такой и должна быть реализация stackless здорового человека, ибо размер фрейма известен во время компиляции.
Точно также как и размер замыкания известен во время компиляции, и мы мыжем просто сохранить всё замыкание через автоматический вывод типа. Представь что вместо конкретного типа замыкания мы бы всегда получали std::function
Отредактировано 09.01.2021 14:59 Evgeny.Panasyuk . Предыдущая версия .
C++20 coroutines (co_await)
От: okman Беларусь https://searchinform.ru/
Дата: 06.01.21 20:34
Оценка: 4 (2)
Всем привет!

Изучаю C++20. В целом все понятно, но одна вещь вызывает наибольшие затруднения — корутины.

Насколько я понял, в C++20 появился некий интерфейс, реализуя который, разработчик может обеспечить нужное ему
поведение, вплоть до низкоуровневых деталей, таких как выполнение задачи в отдельном потоке (например, в Windows
это можно сделать с помощью CreateThreadpoolWork/SubmitThreadpoolWork). Готовую библиотечную реализацию корутин,
как выясняется, не "завезли" (ждите C++23). Я прав?

Ну и тогда главный вопрос: где можно найти более-менее полноценное и толковое описание этого интерфейса?

Я пока плохо понимаю, как связаны task, promise и awaiter, чем отличаются "обычная" корутина и noop-coroutine,
куда конкретно нужно вставлять вызовы co_await/co_yield/co_return. А ведь там еще есть "загадочные" operator
co_await, await_transform, coroutine_handle, разделение на stackfull и stackless...

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

  Скрытый текст
#include <coroutine>
#include <utility>
#include <iostream>
 
template<class T>
struct task {
    struct promise_type {
        auto get_return_object() {
            return task(std::coroutine_handle<promise_type>::from_promise(*this));
        }
        std::suspend_always initial_suspend() { return {}; }
        struct final_awaiter {
            bool await_ready() noexcept { return false; }
            void await_resume() noexcept {}
            std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> h) noexcept {
                // final_awaiter::await_suspend is called when the execution of the
                // current coroutine (referred to by 'h') is about to finish.
                // If the current coroutine was resumed by another coroutine via
                // co_await get_task(), a handle to that coroutine has been stored
                // as h.promise().previous. In that case, return the handle to resume
                // the previous coroutine.
                // Otherwise, return noop_coroutine(), whose resumption does nothing.
 
                auto previous = h.promise().previous;
                if (previous) {
                    return previous;
                } else {
                    return std::noop_coroutine();
                }
            }
        };
        final_awaiter final_suspend() noexcept { return {}; }
        void unhandled_exception() { throw; }
        void return_value(T value) { result = std::move(value); }
        T result;
        std::coroutine_handle<> previous;
    };
 
    task(std::coroutine_handle<promise_type> h) : coro(h) {}
    task(task&& t) = delete;
    ~task() { coro.destroy(); }
 
    struct awaiter {
        bool await_ready() { return false; }
        T await_resume() { return std::move(coro.promise().result); }
        auto await_suspend(std::coroutine_handle<> h) {
            coro.promise().previous = h;
            return coro;
        }
        std::coroutine_handle<promise_type> coro;
    };
    awaiter operator co_await() { return awaiter{coro}; }
    T operator()() {
        coro.resume();
        return std::move(coro.promise().result);
    }
private:
    std::coroutine_handle<promise_type> coro;
};
 
task<int> get_random() {
    std::cout << "in get_random()\n";
    co_return 4;
}
task<int> test() {
    task<int> v = get_random();
    task<int> u = get_random();
    std::cout << "in test()\n";
    int x = (co_await v + co_await u);
    co_return x;
}
 
int main() {
    task<int> t = test();
    int result = t();
    std::cout << result << '\n';
}



Пробовал вникать в примеры на en.cppreference.com, смотрел как устроены асинхронные вызовы в C++/WinRT, был на Хабре,
на MSDN, на MSVC Team Blog, смотрел исходники библиотеки cppcoro, но ясности не прибавилось.

> "Фреймворк для написания корутин состоит из более чем 20 функций которые частично нужно реализовать, а

> частично могут быть переписаны (Хабр, "Корутины в C++20. Часть 1").

Что это за функции? Где про это почитать подробнее? И т.д.


Ссылки ниже, вдруг кому-то пригодится:

Standard library header <coroutine>
https://en.cppreference.com/w/cpp/header/coroutine

C++ Coroutines in Visual Studio 2019 Version 16.8
https://devblogs.microsoft.com/cppblog/c-coroutines-in-visual-studio-2019-version-16-8/

lewissbaker/cppcoro
https://github.com/lewissbaker/cppcoro

C++20. Coroutines
https://habr.com/ru/post/519464/
Re[2]: C++20 coroutines (co_await)
От: okman Беларусь https://searchinform.ru/
Дата: 07.01.21 08:07
Оценка: +2
Здравствуйте, reversecode, Вы писали:

R>если и это не поймете, значит оно не для вас


R>корутины


О, вот эта "новая реальность" меня немного расстраивает.
Теперь документация по языку и его фичам — это или набор слайдов от непонятного чувака, или отсылки ко всяким proposal?
Re[6]: C++20 coroutines (co_await)
От: okman Беларусь https://searchinform.ru/
Дата: 07.01.21 08:14
Оценка: +2
Здравствуйте, reversecode, Вы писали:

R>стейт машину в которые корутины разворачиваются можно кастомизировать в действиях на вход/выход/експрешин/возвращаемые значение

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

reversecode, думаю, не я один был бы весьма благодарен за более подробное и развернутое описание.
Re[2]: C++20 coroutines (co_await)
От: AeroSun  
Дата: 11.04.21 20:24
Оценка: :))
Эти корутины надо закопать, пусть везут новые.
Я хз как из такой простой вещи как корутины им удалось такое болото
Говноархитекторы на марше
Re[6]: C++20 coroutines (co_await)
От: kov_serg Россия  
Дата: 07.01.21 09:06
Оценка: 8 (1)
Здравствуйте, reversecode, Вы писали:

R>стейт машину в которые корутины разворачиваются можно кастомизировать в действиях на вход/выход/експрешин/возвращаемые значение

R>ключевые функции при кастомизации могут быть кастомизированы в разных возврат значениях
R>и это дает еще больше вариантов логики обработки
Вот заглянешь в чужой код и у всех будут свои реализации — шикарно.

R>и хз есть ли в других языках

R>но в С++ можно еще делать симметричные корутины
ждём inlineing для них, что бы в софтовый получить hyperthreading.

R>из не достатков, пока что их не зацепили к сетевым функциям

R>в С++23 обещают и сеть и все остальное завести и прецепить
где публикуют собрание обещаний?

R>корутины в С++ стейтлесс, как и у раста

R>в отличии от гоу и питона где они вроде бы стекфул
а dynamic memory less есть?

https://gist.github.com/MattPD/9b55db49537a90545a90447392ad3aeb
Re: C++20 coroutines (co_await)
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 11.04.21 12:26
Оценка: 8 (1)
Здравствуйте, okman, Вы писали:

O>Изучаю C++20. В целом все понятно, но одна вещь вызывает наибольшие затруднения — корутины.


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

Но, если хорошо поискать, то можно найти нормальное и детальное описание вот тут: https://www.scs.stanford.edu/~dm/blog/c++-coroutines.html
Отредактировано 11.04.2021 12:29 kaa.python . Предыдущая версия . Еще …
Отредактировано 11.04.2021 12:27 kaa.python . Предыдущая версия .
Re[2]: C++20 coroutines (co_await)
От: okman Беларусь https://searchinform.ru/
Дата: 07.01.21 08:12
Оценка: +1
Здравствуйте, Kernan, Вы писали:

K>А неужели никто научной/полунаучной статьи на эту тематику не написал?


Так даже не статью ищу, а просто нормальную доку с описанием классов/методов и хотя бы поверхностным "how to".
А в таком виде как сейчас оно просто неюзабельно, по крайней мере для меня. Как можно использовать то, что недокументированно?
Даже на MSDN нет почти никакого описания, кроме ссылок на 2-3 статьи в блоге...
Re[4]: C++20 coroutines (co_await)
От: okman Беларусь https://searchinform.ru/
Дата: 07.01.21 12:33
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>https://en.cppreference.com/w/cpp/language/coroutines


R>Вот это смотрел уже?


Да, здесь уже был. По описанию на этой странице я и пробовал разобраться. Конкретно здесь непонятно, как действовать, если корутина
должна вернуть какой-то результат, например int. Откуда его забирать? Глядя на код не ясно, как между собой взаимодействуют
классы promise_type, task и awaitable.

В других сэмплах (там же) они в get_return_object возвращают std::coroutine_handle<promise_type>::from_promise(*this) — для
человека, который первый раз смотрит на такое, это как минимум не очевидно...
Re[7]: C++20 coroutines (co_await)
От: B0FEE664  
Дата: 07.01.21 20:00
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>>>Это для слова калька-то не было собственного слова??

ЕМ>>Ну так откройте его, не томите.
R>Выбирай: Синонимы к слову «калька»

Там интересные примеры:

В послевоенные годы множество калек нуждались в помощи пластических хирургов.

И каждый день — без права на ошибку...
Re[5]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 10.01.21 10:24
Оценка: +1
Здравствуйте, х, Вы писали:

х>Там можно new перекрыть в promise, чтобы оптимизировать аллокаторы.


А можно было бы вообще обойтись без аллокации, так же как и для обычных лямбд/замыканий.
И потом, даже если делать in-place аллокатор для небольших корутин — то скроей всего будет либо перерасход памяти, либо таки аллокация в куче.
Re[6]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 10.01.21 10:39
Оценка: +1
Здравствуйте, х, Вы писали:

EP>>Вопрос не про типизацацию в плане безопасности, а про стирание типа, type erasure. Ибо я именно что стирание типа и наблюдаю — std::coroutine_handle, каковым оно и было в ранних версиях.

х>а чем плох type erasure в данном случае? Насколько я понял, конкретный тип лежит в параметре шаблона U и можно попробовать его анализировать.

Там конкретный тип promise, а не конкретной корутины. Разные корутины выдающие один и тот же promise, могут иметь разный размер, так как имеют разный размер фрейма.

х>Но зачем? Можно пример?


Представь что если бы у обычного замыкания, не было конкретного типа, а всегда был тип std::function
std::function<void()> type_erased_labmda = [=]{ ... };

И все замыкания, независимо от размера их контекста, всегда бы имели один и тот же тип.
Это привело бы к неменуемым аллокациям (разные замыканиия имеют разный контекст, и соответсвенно разный размер, и поэтому все не могут быть сохранены целиком в один и тот же тип sizeof которого фиксирован), и проблемам с оптимизацией. Вот в случае с сабжем, мы именно это и получили

EP>>Если разные генераторы, с разным набором и колличеством локальных переменных можно сохранить в один и тот же тип — то это и есть стирание типов, которого по-хорошему быть не должно. То есть оно может быть опциональным, по-желанию, как и std::function для замыканий, но не долнжо быть единственным вариантом.

х>Если Вы про то что так трудно контролировать время жизни конкретного аргумента, то соглашусь. Можете привести другие примеры почему в данном случае "стирание типов ... быть не должно"?

Проблемы с контролем времени жизни нет, даже при стирании типа — тот же std::function имеет вполне нормальное время жизни.
Проблема есть с тем что мы не можем целиком сохранить целиком корутину в поле объекта. Проблема в том что при комбинировании корутин с алгортимами, даже если алгоритм шаблонный — то будет проблема с оптимизацией, так как для всех генераторов будет выводится один и тот же тип, и оптимизации без инлайнинга вообще не будет (которая есть в нормальных случаях, ибо шаблон инстанцируется под конкретный объект).
Когда я использую генераторы (например генератор выпрявляющий vector<vector<int>> в один range из int'ов), я хочу чтобы результат по скорости не отличался от вручную оптимизированного — zero-overhead — тоже самое что мы уже имеем с замыканиями, с сабжем так не получися, увы.
Re[14]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 17.01.21 08:57
Оценка: +1
Здравствуйте, х, Вы писали:

EP>>Точно также как и с лямбдами — их код должен быть доступен, потому что по факту они определяют новый анонимный тип, то же самое и с корутинами.

х>Ну так бы сразу и сказал, что предлагаешь инлайнить корутины.

Ну я сразу сказал что не хочу безалтернативное стирание типа.

х>Я пас: это убьёт саму идею спрятать кишки работы с сетью и другими устройствами в корутины.


1. Это, извиняюсь, откровенная чушь. Ибо возможность "прятать кишки" никуда не исчезла. Точно также как и сейчас можно сделать:
std::function<int()> make();
И "спрятать кишки", в которых может быть хоть обычный тип, хоть лямбда, не смотря на то что у лямбды вполне конкретный тип и размер.

2. Корутины они не только для работы с сетью и устройствами, там действительно в большинстве случаев лишняя аллокация не так страшна. На них ещё можно делать генераторы, которые очень широко применимы И для которых эта лишняя аллокация плюс убийство инлайнинга очень сильно сужает область практического применения
Re[2]: C++20 coroutines (co_await)
От: bnk СССР http://unmanagedvisio.com/
Дата: 06.01.21 23:16
Оценка:
Здравствуйте, reversecode, Вы писали:

R>если и это не поймете, значит оно не для вас


R>корутины


Я правильно понимаю, что это просто async/await наконец сделали в С++? Или это что-то большее?
В смысле, async/await по типу как он есть в С#, javascript, и т.п.?
Отредактировано 06.01.2021 23:29 bnk . Предыдущая версия .
Re[4]: C++20 coroutines (co_await)
От: bnk СССР http://unmanagedvisio.com/
Дата: 06.01.21 23:34
Оценка:
Здравствуйте, reversecode, Вы писали:

R>можно и так сказать

R>только сделали сильно круче чем в расте или других языках
R>очень огромные возможности для кастомизации

Ну если это даже круче чем у других, то это конечно хорошо.
Посмотрел вики выглядит вроде практически так же как и в других языках.
https://en.wikipedia.org/wiki/Async/await

А в чем крутость по сравнению с остальными, если в дух словах?
Re[5]: C++20 coroutines (co_await)
От: landerhigh Пират  
Дата: 06.01.21 23:46
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>А в чем крутость по сравнению с остальными, если в дух словах?


Не уверен насчет крутости. Пока сам не использовал всерьез, лишь игрался невсерьез.

-Они stackless. Значит, yield'ануть из глубин вложенных вызовов функций не выйдет.
+Они stackelss. Значит, оверхед по памяти ограничен и оверхед на переключение контекста должен быть минимальным

Этот плюс, имхо, должен перекрывать минус на порядок.
www.blinnov.com
Re[5]: C++20 coroutines (co_await)
От: reversecode google
Дата: 06.01.21 23:49
Оценка:
стейт машину в которые корутины разворачиваются можно кастомизировать в действиях на вход/выход/експрешин/возвращаемые значение
ключевые функции при кастомизации могут быть кастомизированы в разных возврат значениях
и это дает еще больше вариантов логики обработки

и хз есть ли в других языках
но в С++ можно еще делать симметричные корутины

из не достатков, пока что их не зацепили к сетевым функциям
в С++23 обещают и сеть и все остальное завести и прецепить

но asio уже можно с ними использовать
или свою логику над сокетами и таймерами если хоцца

корутины в С++ стейтлесс, как и у раста
в отличии от гоу и питона где они вроде бы стекфул
Re[5]: C++20 coroutines (co_await)
От: Тёмчик Австралия жж
Дата: 07.01.21 05:10
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>А в чем крутость по сравнению с остальными, если в дух словах?


— Чем круче корутин в C++ чем в C# (Python, JS, десятки их)?
— Тем, что в C++.
Re: C++20 coroutines (co_await)
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 07.01.21 06:48
Оценка:
Здравствуйте, okman, Вы писали:

O>Изучаю C++20. В целом все понятно, но одна вещь вызывает наибольшие затруднения — корутины.

А неужели никто научной/полунаучной статьи на эту тематику не написал?
Sic luceat lux!
Re[3]: C++20 coroutines (co_await)
От: rg45 СССР  
Дата: 07.01.21 10:04
Оценка:
Здравствуйте, okman, Вы писали:

O>Так даже не статью ищу, а просто нормальную доку с описанием классов/методов и хотя бы поверхностным "how to".

O>А в таком виде как сейчас оно просто неюзабельно, по крайней мере для меня. Как можно использовать то, что недокументированно?
O>Даже на MSDN нет почти никакого описания, кроме ссылок на 2-3 статьи в блоге...

https://en.cppreference.com/w/cpp/language/coroutines

Вот это смотрел уже?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: C++20 coroutines (co_await)
От: reversecode google
Дата: 07.01.21 10:56
Оценка:
офф дока стандарта вам не зашла
ок
если и ссылка на разжевывание с картинками и стрелочками на русском вам не зашла
значит это или такой троллинг или корутины не для вас
Re[2]: C++20 coroutines (co_await)
От: reversecode google
Дата: 07.01.21 11:43
Оценка:
F>Но вообще, тоже подпишусь в надежде на достойную доку.

мифическая дока... ну что ж, будем ждать ее

у кого есть связь с комитетом ?
пусть напишут правильную доку по корутинам, а то ж никому ничего не понятно
Re[6]: C++20 coroutines (co_await)
От: vopl Россия  
Дата: 07.01.21 11:58
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>-Они stackless. Значит, yield'ануть из глубин вложенных вызовов функций не выйдет.


А можешь конкретный пример привести, пожалуйста?
Re[6]: C++20 coroutines (co_await)
От: reversecode google
Дата: 07.01.21 12:03
Оценка:
L>-Они stackless. Значит, yield'ануть из глубин вложенных вызовов функций не выйдет.

получиться, если есть хендл на корутину на которую нужно перейти(выпрыгнуть)
Re[7]: C++20 coroutines (co_await)
От: landerhigh Пират  
Дата: 07.01.21 12:27
Оценка:
Здравствуйте, reversecode, Вы писали:


L>>-Они stackless. Значит, yield'ануть из глубин вложенных вызовов функций не выйдет.


R>получиться, если есть хендл на корутину на которую нужно перейти(выпрыгнуть)


не получится


void someNestedFunction(coro someCoro)
{
    int a = soSomething();
    if (nothing())
    {
        someCoro.yield();
        use(a);  // упс.
    }
}
www.blinnov.com
Re[8]: C++20 coroutines (co_await)
От: reversecode google
Дата: 07.01.21 12:32
Оценка:
этот упс не соберется в С++
по стандарту С++, функция считается корутиной если в ней присутствует одно из ключевых слов co_*

а в вашем примере хз что такое yield
а вот co_return из текущей корутины, запросто выпрыгнет в любую другую корутину если переопределен await_suspend и есть хендл той корутины куда прыгать
Отредактировано 07.01.2021 13:16 reversecode . Предыдущая версия .
Re[4]: C++20 coroutines (co_await)
От: okman Беларусь https://searchinform.ru/
Дата: 07.01.21 12:35
Оценка:
Здравствуйте, reversecode, Вы писали:

R>офф дока стандарта вам не зашла

R>ок
R>если и ссылка на разжевывание с картинками и стрелочками на русском вам не зашла
R>значит это или такой троллинг или корутины не для вас

За ссылку спасибо, но "разжевывание" не отвечает на вопросы. Например, что такое симметричная корутина или noop-корутина.
Re: C++20 coroutines (co_await)
От: AeroSun  
Дата: 07.01.21 12:39
Оценка:
Это как с модулями — ближайшие лет 10 можно даже не смотреть в ту сторону.
В том состоянии, в каком они сегодня — это просто задел хотелок на будущее.
Re[5]: C++20 coroutines (co_await)
От: reversecode google
Дата: 07.01.21 12:39
Оценка:
считайте нооп как нуллптр и относится как раз к симетричным корутинам
о которых сейчас с блиновым выше дискутируем
когда выход "yield" выпрыгивает не из текущей корутины
а переходит в какую то другую корутину

а не симметричная это обычное поведение когда выходит(выпрыгивает) с текущей
Re[9]: C++20 coroutines (co_await)
От: landerhigh Пират  
Дата: 07.01.21 12:40
Оценка:
Здравствуйте, reversecode, Вы писали:

R>этот упс не соберется в С++

R>по стандарту С++, функция считается корутиной если в ней присутствует одно из ключевых слов co_*

Вот в случае со stackful корутинами такого ограничения нет. Функции в дереве вызовов вообще могут не знать, что они выполняются в контексте корутины.

R>а в вашем примере хз что такое yield


Это ж очевидно — это интерфейс stackful корутины.
www.blinnov.com
Отредактировано 07.01.2021 18:42 landerhigh . Предыдущая версия .
Re[3]: C++20 coroutines (co_await)
От: B0FEE664  
Дата: 07.01.21 13:19
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Я правильно понимаю, что это просто async/await наконец сделали в С++? Или это что-то большее?

Простые async/await ещё в C++11 доступны были
И каждый день — без права на ошибку...
Re: А нельзя
От: Ватакуси Россия  
Дата: 07.01.21 15:09
Оценка:
Разобраться как это в том же питоне работает, а потом с этим вернуться в С++?
Все будет Украина!
Re[2]: А нельзя
От: reversecode google
Дата: 07.01.21 15:14
Оценка:
научившись ездить на велосипеде, летать на боинге не получиться, да и опыт будет не релевантный
Re[3]: А нельзя
От: Ватакуси Россия  
Дата: 07.01.21 16:16
Оценка:
R>научившись ездить на велосипеде, летать на боинге не получиться, да и опыт будет не релевантный

Ну, не знаю — если там понять принципы, а потом их уже применять в С++.
Все будет Украина!
Re[2]: C++20 coroutines (co_await)
От: rg45 СССР  
Дата: 07.01.21 16:16
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

O>>корутины.


ЕМ>Отчего эта корявая калька так расплодилась в народе? Есть же (еще с середины прошлого века) отличный термин — сопрограммы. Прям тест на знание истории программирования.


Странно, что тебя совершенно не смущает, что слово калька также является заимствованным из иностранного языка. Как и слово "программа", кстати.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 07.01.2021 16:34 rg45 . Предыдущая версия .
Re[4]: C++20 coroutines (co_await)
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.01.21 17:27
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

R>>Странно, что тебя совершенно не смущает, что слово калька также является заимствованным из иностранного языка. Как и слово "программа", кстати.


ЕМ>Совершенно не смущает. Эти слова, как и "экран", "процессор" и прочие, обозначают понятия, для которых в русском языке на момент заимствования не было собственных слов. Это естественный процесс развития любого языка.


ЕМ>А "корутина" — столь же тупое передирание иностранного слова в кириллицу, сколь и "менеджмент", "супервайзинг" и подобное. В оборот их вводят те, кто толком не знает родного языка, а распространяют те, кто этого языка не уважает.


Так как "программа" тоже заимствовано, но чуть раньше — это напоминает реплику одного деятеля из 90-х, который жаловался на заимствование слова "файрволл", когда уже в языке было "исконно русское" "брандмауэр" (заимствованное на пару лет раньше)

Мне к тому же не нравится, что "сопрограмма" может иметь смысл "работающий рядом процесс", в отличие от "корутина". Хотя "подпрограмма" прижилось, а "субрутина" — нет. Видимо, слишком сильна была ассоциация с "рутина".

Героическая борьба мыла с шилом, в общем...
The God is real, unless declared integer.
Re[4]: C++20 coroutines (co_await)
От: rg45 СССР  
Дата: 07.01.21 17:32
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

R>>Странно, что тебя совершенно не смущает, что слово калька также является заимствованным из иностранного языка. Как и слово "программа", кстати.


ЕМ>Совершенно не смущает. Эти слова, как и "экран", "процессор" и прочие, обозначают понятия, для которых в русском языке на момент заимствования не было собственных слов. Это естественный процесс развития любого языка.


Это для слова калька-то не было собственного слова?? Чего только не выдумают люди...
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: C++20 coroutines (co_await)
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.01.21 17:37
Оценка:
Здравствуйте, netch80, Вы писали:

N>напоминает реплику одного деятеля из 90-х, который жаловался на заимствование слова "файрволл", когда уже в языке было "исконно русское" "брандмауэр" (заимствованное на пару лет раньше)


Слово "брандмауэр" было заимствовано лет двести назад, если не раньше. В значении "сетевой экран", насколько я помню, его впервые использовали в XP (2001-й), куда он был встроен, а "файрвол" вроде как начал входить в употребление еще в конце 90-х, когда появилось само понятие.

N>Мне к тому же не нравится, что "сопрограмма" может иметь смысл "работающий рядом процесс"


Не может, если знать уже сложившуюся терминологию. Слово "сопрограмма" нередко упоминалось в литературе 60-80-х в совершенно конкретном смысла. А потом в перестройку поперли кривые переводы с английского, и половина терминов была забыта.
Re[5]: C++20 coroutines (co_await)
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.01.21 19:29
Оценка:
Здравствуйте, rg45, Вы писали:

R>Это для слова калька-то не было собственного слова??


Ну так откройте его, не томите.
Re[6]: C++20 coroutines (co_await)
От: rg45 СССР  
Дата: 07.01.21 19:38
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

R>>Это для слова калька-то не было собственного слова??


ЕМ>Ну так откройте его, не томите.


Выбирай: Синонимы к слову «калька»

От себя еще накину пару-тройку: сдувание, передирание, сдирание, передувание.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 07.01.2021 19:41 rg45 . Предыдущая версия .
Re[8]: C++20 coroutines (co_await)
От: rg45 СССР  
Дата: 07.01.21 20:05
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Там интересные примеры:

BFE>

BFE>В послевоенные годы множество калек нуждались в помощи пластических хирургов.


Так это только расширяет набор синонимов, а значит, укрепляет мою дискуссионную позицию
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[7]: C++20 coroutines (co_await)
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.01.21 20:07
Оценка:
Здравствуйте, rg45, Вы писали:

R>Выбирай: Синонимы к слову «калька»

R>От себя еще накину пару-тройку: сдувание, передирание, сдирание, передувание.

И какой из них, на Ваш взгляд, следовало использовать в качестве официального термина в науке лингвистике?
Re[8]: C++20 coroutines (co_await)
От: rg45 СССР  
Дата: 07.01.21 20:10
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>И какой из них, на Ваш взгляд, следовало использовать в качестве официального термина в науке лингвистике?


Я предоставляют тебе право выбора. В какой из перечисленных категорий, на твой взгляд, слово "калька" было первым и не имело аналогов?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: C++20 coroutines (co_await)
От: student__  
Дата: 07.01.21 21:38
Оценка:
Так это новый виток в эре копроэкономики наступил, когда вместо грамотной технической документации в сеть выплевывается либо автоматически сгенерированная справочная информация, жиденько откомментированная специалистом, либо поток сознания в виде тех же proposal, написанных, как средневековые философские трактаты, с закосом на наукообразность. А в опенсорс это вообще модус операнди, ведь продукт с его использованием делает только капиталист. А твоя де факто обязанность как инженера — социализация внутри релевантной тусовки инженеров, и попутное выяснение актуальных измениний в проекте. Вобщем-то, так всегда было, но чем больше капитал использует квалифицированную рабскую силу (опенсорс), тем больше подразумевается, что "все эти хомячки-хакеры... им же только хавку регулярно подбрасывай, а они там уже сами в своем кругу разберутся, какую документацию, и в каком виде писать, и типа организовывать их не нужно".
Отредактировано 07.01.2021 21:40 student__ . Предыдущая версия . Еще …
Отредактировано 07.01.2021 21:39 student__ . Предыдущая версия .
Отредактировано 07.01.2021 21:38 student__ . Предыдущая версия .
Re[10]: C++20 coroutines (co_await)
От: reversecode google
Дата: 07.01.21 21:49
Оценка:
причем здесь стекфул корутины в контексте обсуждаемой имплементации в С++ стеклесс ?

вообще все очень притянуто зауши учитывая что я за последние лет 10
и стекфул корутин не наблюдал в любом маломайски популярном или топ нейм продукте на С или С++
Re: C++20 coroutines (co_await)
От: _NN_ www.nemerleweb.com
Дата: 08.01.21 06:46
Оценка:
Здравствуйте, okman, Вы писали:

O>как выясняется, не "завезли" (ждите C++23). Я прав?


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

Можете посмотреть разработку коллеги как раз решающую эту проблему.
cncurencpp
Автор: _NN_
Дата: 06.08.20
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 14:50
Оценка:
Здравствуйте, х, Вы писали:

х>преобразуется в что-то вида:


Подскажи пожалуйста, они дали возможность сохранить корутину через её конкретный тип, или там до сих пор есть стирание типа вытекающие в аллокацию (которое было в ранних вариантах)?
Re[3]: C++20 coroutines (co_await)
От: х Россия  
Дата: 09.01.21 15:08
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Подскажи пожалуйста, они дали возможность сохранить корутину через её конкретный тип, или там до сих пор есть стирание типа вытекающие в аллокацию (которое было в ранних вариантах)?


Всё типилизированно. Тут реальная обёртка текущая под clang.
С уважением Вадим.
Re[7]: C++20 coroutines (co_await)
От: reversecode google
Дата: 09.01.21 15:11
Оценка:
а как бы вы сделали симметричные стеклесс корутины без аллокации фрейма ?
Re[4]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 15:41
Оценка:
Здравствуйте, х, Вы писали:

EP>>Подскажи пожалуйста, они дали возможность сохранить корутину через её конкретный тип, или там до сих пор есть стирание типа вытекающие в аллокацию (которое было в ранних вариантах)?

х>Всё типилизированно. Тут реальная обёртка текущая под clang.

Вопрос не про типизацацию в плане безопасности, а про стирание типа, type erasure. Ибо я именно что стирание типа и наблюдаю — std::coroutine_handle, каковым оно и было в ранних версиях.
Если разные генераторы, с разным набором и колличеством локальных переменных можно сохранить в один и тот же тип — то это и есть стирание типов, которого по-хорошему быть не должно. То есть оно может быть опциональным, по-желанию, как и std::function для замыканий, но не долнжо быть единственным вариантом.
Re[8]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 16:10
Оценка:
Здравствуйте, reversecode, Вы писали:

R>а как бы вы сделали симметричные стеклесс корутины без аллокации фрейма ?


Сабжевые ассиметричные.

Stackless корутины есть в Boost.Asio — https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/reference/coroutine.html
Локальное состояние и номер состояния преобразуется в поля класса, просыпание в нужное состояние происодит свитчем. Конкретный экземпляр корутины это объект этого класса у которго есть operator(). Всё состояине известно на этапе компиляции, также как и у лямбды-замыкания, поэтому аллокация не нужна.
Более того, такая конструкция не только позвоялет избавится от аллокации, но также и копировать корутины — что по сути является fork'ом. Ещё круче, что их можно сериализировать.

Автор Asio даже предлагал свой вариант в стандарт, без аллокаций — http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4244.pdf
Но Microsoft видимо продавили свою версию, так как у них уже была своя реализация Они её ещё иногда называют "negative overhead abstraction", с аллокациями ага, негатив блин
Отредактировано 09.01.2021 16:11 Evgeny.Panasyuk . Предыдущая версия .
Re[9]: C++20 coroutines (co_await)
От: reversecode google
Дата: 09.01.21 16:19
Оценка:
сабжевые какие, которые сейчас добавили в стандарт С++ ?
так там они и симметричные тоже

но на вопрос вы не ответили
Re[10]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 16:23
Оценка:
R>но на вопрос вы не ответили

Что именно не ясно? Вот ещё нашёл пример await'а на макросах и stackless корутинах из Asio.
Re[11]: C++20 coroutines (co_await)
От: reversecode google
Дата: 09.01.21 16:30
Оценка:
ассиметричные стеклесс корутины легко реализуются на макросах
симметричные стеклесс корутины на макросах нельзя сделать, поскольку есть контекст
а вот стекфулл симметричные легко
поэтому в сабже и сделали динамическое аллоцирование фрейма, через который можно переключаться
Re[12]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 16:42
Оценка:
Здравствуйте, reversecode, Вы писали:

R>ассиметричные стеклесс корутины легко реализуются на макросах

R>симметричные стеклесс корутины на макросах нельзя сделать, поскольку есть контекст
R>а вот стекфулл симметричные легко
R>поэтому в сабже и сделали динамическое аллоцирование фрейма, через который можно переключаться

Имея конкретный тип ассиметричной корутины её можно аллоцировать на стэке, в поле другого объекта, либо напрямую в куче. Симметричные корутины можно реализовать поверх ассиметричных.
Для многих use-case'ов подходят ассиметричные корутины на стэке, либо вообще заинлайненые по самые помидоры. Например для генераторов типа Python'ского yield. Авторы же сабжа в таких случаях предлагают уповать на то что оптимизатор может выкинуть аллокацию — HALO (heap allocation elision optimization) — но это ганатированно не работает при сохранении корутины в поле другого объекта.
Re[7]: C++20 coroutines (co_await)
От: reversecode google
Дата: 09.01.21 17:00
Оценка:
стекфулл корутины очевидно не добавили в стандарт не потому что они легко реализуются самостоятельно
а потому что необходимо будет описать что такое стек(вспоминая Полухина и его бектрейс)
а за этим потянется и расщирения стека и перемещение объектов по стеку не нарушая их состояния, наверняка у комитета от этого взрывался мозг
я бы сказал по этому стекфулл корутины не очень юзабельны в С++

следить ручками и глазками за размером стека и пытаться сразу же угадать сколько нужно аллоцировать памяти на очередной фрейм это
Re[8]: C++20 coroutines (co_await)
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 09.01.21 17:09
Оценка:
Здравствуйте, reversecode, Вы писали:

R>я бы сказал по этому стекфулл корутины не очень юзабельны в С++

R>следить ручками и глазками за размером стека и пытаться сразу же угадать сколько нужно аллоцировать памяти на очередной фрейм это

Вотчить хэндами и айсами за сайзом и аттемптить саппозинг эмаунта спейса...
Re[8]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 17:23
Оценка:
Здравствуйте, reversecode, Вы писали:

R>стекфулл корутины очевидно не добавили в стандарт не потому что они легко реализуются самостоятельно

R>а потому что необходимо будет описать что такое стек(вспоминая Полухина и его бектрейс)
R>а за этим потянется и расщирения стека и перемещение объектов по стеку не нарушая их состояния, наверняка у комитета от этого взрывался мозг

Перемещение объектов по стэку у stackful корутин врядли кода либо будет, в общем случае это вообще не реализуемо, либо с очень жёсткими ограничениями на вызываемый код, что убьёт всё мощь stackful — ибо они могут работать и прыгать через сторонний код.

R>я бы сказал по этому стекфулл корутины не очень юзабельны в С++


Даже библиотечная реализация достаточно юзабельная.
А вот stackless не очень, поэтому если есть выбор лично я предпочту stackless реализацию в стандарте, так как stackful по сути уже доступна.

R>следить ручками и глазками за размером стека и пытаться сразу же угадать сколько нужно аллоцировать памяти на очередной фрейм это


Ну здесь очевидно непонимание, ибо следить и угадывать размер ручками не нужно и никто не предлагает, даже в макро-реализации stackless из Asio.
Размер фрейма любой функции тривиально известен во время компиляции. Глубина прыжков stackless корутин огранична scope'ом одной фукции, что в C++20, что в C#, что в Python, на то они и stackless. Поэтому и размер корутины, как и её конкретный тип легко может быть известен во время компиляции
Re[9]: C++20 coroutines (co_await)
От: night beast СССР  
Дата: 09.01.21 17:26
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Даже библиотечная реализация достаточно юзабельная.

EP>А вот stackless не очень, поэтому если есть выбор лично я предпочту stackless реализацию в стандарте, так как stackful по сути уже доступна.

я бы предпочел иметь их обоих в стандарте, потому как тащить буст только ради них никто не будет
Re[9]: C++20 coroutines (co_await)
От: reversecode google
Дата: 09.01.21 17:45
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, reversecode, Вы писали:


R>>стекфулл корутины очевидно не добавили в стандарт не потому что они легко реализуются самостоятельно

R>>а потому что необходимо будет описать что такое стек(вспоминая Полухина и его бектрейс)
R>>а за этим потянется и расщирения стека и перемещение объектов по стеку не нарушая их состояния, наверняка у комитета от этого взрывался мозг

EP>Перемещение объектов по стэку у stackful корутин врядли кода либо будет, в общем случае это вообще не реализуемо, либо с очень жёсткими ограничениями на вызываемый код, что убьёт всё мощь stackful — ибо они могут работать и прыгать через сторонний код.


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

R>>я бы сказал по этому стекфулл корутины не очень юзабельны в С++


EP>Даже библиотечная реализация достаточно юзабельная.

EP>А вот stackless не очень, поэтому если есть выбор лично я предпочту stackless реализацию в стандарте, так как stackful по сути уже доступна.

R>>следить ручками и глазками за размером стека и пытаться сразу же угадать сколько нужно аллоцировать памяти на очередной фрейм это


EP>Ну здесь очевидно непонимание, ибо следить и угадывать размер ручками не нужно и никто не предлагает, даже в макро-реализации stackless из Asio.

EP>Размер фрейма любой функции тривиально известен во время компиляции. Глубина прыжков stackless корутин огранична scope'ом одной фукции, что в C++20, что в C#, что в Python, на то они и stackless. Поэтому и размер корутины, как и её конкретный тип легко может быть известен во время компиляции

я говорил про стекфулл корутины, сколько вы аллоцируете памяти на каждую стекфулл корутину ?
а в бусте ?
а про обработку исключений вы наверное тоже не забыли ?
в том же гоуланг об этом думать не надо, памяти они перераспределят автоматически если стек выростет

короче говоря, стекфулл корутины в С++ нужны как минимум такие как они уже есть в гоуланг
либо они не нужны вообще

в свое время я даже реверснул имплементацию асинхронщины у яндекса о которой они часто рассказывали на докладах,тот же Иван Пузыревский помоему
они там тоже взяли бустовую реализацию
подпилили для большей скорости переключения
окучили исключения
сделали мультифутуры(когда футура может по несколько раз возвщарать значение а не один раз как стандартная)
но даже там стек аллоцируют на глаз
и корутиной сделали саму так сказать футуру в которой стек почти никуда не растет

и хотя в целом имплементация у них "прикольная"
для больших хайлоад на мой взгляд не очень юзабельная

я к чему ? к тому что стекфулл корутины в С++ для поиграться и не больших проектов
  ждем флуда
про то как всякие расспределенны БД юзают стекфулл корутины
Re[10]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 17:47
Оценка:
Здравствуйте, night beast, Вы писали:

EP>>Даже библиотечная реализация достаточно юзабельная.

EP>>А вот stackless не очень, поэтому если есть выбор лично я предпочту stackless реализацию в стандарте, так как stackful по сути уже доступна.

NB>я бы предпочел иметь их обоих в стандарте,


Я согласен — лучше и то и другое, ибо и там и там есть свои сильные и слабые стороны. Например у stackless ограниченна глубина и они нельзя прыгнуть через чужой код, у stackful могут быть проблемы с размером стэка, их не сделать копируемыми/сериализуемыми, более тяжёлые переключения контекста.

NB>потому как тащить буст только ради них никто не будет


Обычно он уже есть. В крайнем случае можно самому напедалить. А вот нормальные stackless увы нет.
Re[10]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 09.01.21 18:06
Оценка:
Здравствуйте, reversecode, Вы писали:

R>>>стекфулл корутины очевидно не добавили в стандарт не потому что они легко реализуются самостоятельно

R>>>а потому что необходимо будет описать что такое стек(вспоминая Полухина и его бектрейс)
R>>>а за этим потянется и расщирения стека и перемещение объектов по стеку не нарушая их состояния, наверняка у комитета от этого взрывался мозг
EP>>Перемещение объектов по стэку у stackful корутин врядли кода либо будет, в общем случае это вообще не реализуемо, либо с очень жёсткими ограничениями на вызываемый код, что убьёт всё мощь stackful — ибо они могут работать и прыгать через сторонний код.
R> при расширении границы стека это неизбежно,

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

R>>>следить ручками и глазками за размером стека и пытаться сразу же угадать сколько нужно аллоцировать памяти на очередной фрейм это

EP>>Ну здесь очевидно непонимание, ибо следить и угадывать размер ручками не нужно и никто не предлагает, даже в макро-реализации stackless из Asio.
EP>>Размер фрейма любой функции тривиально известен во время компиляции. Глубина прыжков stackless корутин огранична scope'ом одной фукции, что в C++20, что в C#, что в Python, на то они и stackless. Поэтому и размер корутины, как и её конкретный тип легко может быть известен во время компиляции
R>я говорил про стекфулл корутины, сколько вы аллоцируете памяти на каждую стекфулл корутину ?
R>а в бусте ?

Это параметр. В том числе может быть сегментированный стэк

https://www.boost.org/doc/libs/1_75_0/libs/coroutine2/doc/html/coroutine2/stack/segmented.html
Boost.Coroutine2 supports usage of a segmented_stack, e. g. the size of the stack grows on demand. The coroutine is created with a minimal stack size and will be increased as required


R>а про обработку исключений вы наверное тоже не забыли ?


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

R>в том же гоуланг об этом думать не надо


Ну да, нет исключений, нет проблем — педальте вручную.

R>и хотя в целом имплементация у них "прикольная"

R>для больших хайлоад на мой взгляд не очень юзабельная

R>я к чему ? к тому что стекфулл корутины в С++ для поиграться и не больших проектов


Ты свое мнение сформировал — удачи
Re[11]: C++20 coroutines (co_await)
От: night beast СССР  
Дата: 09.01.21 18:17
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

NB>>потому как тащить буст только ради них никто не будет


EP>Обычно он уже есть. В крайнем случае можно самому напедалить.


платформонезависимо не напедалить
Re[11]: C++20 coroutines (co_await)
От: landerhigh Пират  
Дата: 10.01.21 00:04
Оценка:
Здравствуйте, reversecode, Вы писали:

R> причем здесь стекфул корутины в контексте обсуждаемой имплементации в С++ стеклесс ?


Я упомянул.
Мне все равно не очень понятно, почему стекфул не были предложены в стандарт.

R>вообще все очень притянуто зауши учитывая что я за последние лет 10

R>и стекфул корутин не наблюдал в любом маломайски популярном или топ нейм продукте на С или С++

Одна из ведущих SCADA систем, установленная в 80% датацентров и еще черт знает где, имеет в себе модули с корутинами на boost::context (boost::coroutine еще не было)
www.blinnov.com
Re[3]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 10.01.21 04:29
Оценка:
EP>Подскажи пожалуйста, они дали возможность сохранить корутину через её конкретный тип, или там до сих пор есть стирание типа вытекающие в аллокацию (которое было в ранних вариантах)?

Походу стирание конкретного типа и аллокацию таки оставили:

https://en.cppreference.com/w/cpp/language/coroutines
Each coroutine is associated with
* the coroutine state, which is an internal, heap-allocated (unless the allocation is optimized out)

спасибо майкрософт за это
Re[2]: C++20 coroutines (co_await)
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 10.01.21 05:09
Оценка:
Здравствуйте, student__, Вы писали:

__>Так это новый виток в эре копроэкономики наступил

Либо ты просто не понимаешь что там написано из-за отсутствия нужных знаний.
Sic luceat lux!
Re[5]: C++20 coroutines (co_await)
От: х Россия  
Дата: 10.01.21 07:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Вопрос не про типизацацию в плане безопасности, а про стирание типа, type erasure. Ибо я именно что стирание типа и наблюдаю — std::coroutine_handle, каковым оно и было в ранних версиях.


а чем плох type erasure в данном случае? Насколько я понял, конкретный тип лежит в параметре шаблона U и можно попробовать его анализировать. Но зачем? Можно пример?

EP>Если разные генераторы, с разным набором и колличеством локальных переменных можно сохранить в один и тот же тип — то это и есть стирание типов, которого по-хорошему быть не должно. То есть оно может быть опциональным, по-желанию, как и std::function для замыканий, но не долнжо быть единственным вариантом.


Если Вы про то что так трудно контролировать время жизни конкретного аргумента, то соглашусь. Можете привести другие примеры почему в данном случае "стирание типов ... быть не должно"?
С уважением Вадим.
Re[4]: C++20 coroutines (co_await)
От: х Россия  
Дата: 10.01.21 07:49
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Походу стирание конкретного типа и аллокацию таки оставили:

EP>

EP>https://en.cppreference.com/w/cpp/language/coroutines
EP>Each coroutine is associated with
EP>* the coroutine state, which is an internal, heap-allocated (unless the allocation is optimized out)

EP>спасибо майкрософт за это

Там можно new перекрыть в promise, чтобы оптимизировать аллокаторы.
С уважением Вадим.
Re[10]: C++20 coroutines (co_await)
От: landerhigh Пират  
Дата: 10.01.21 09:53
Оценка:
Здравствуйте, reversecode, Вы писали:

R>я к чему ? к тому что стекфулл корутины в С++ для поиграться и не больших проектов


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

Но в процессе разработки выяснили, что MS опять кое-что не совсем полностью документировали и при интеропе CLR->C++->boost::context->CLR CLR выдавал ошибку out of memory.
Удалось пофиксить в boost::context
www.blinnov.com
Re[6]: C++20 coroutines (co_await)
От: х Россия  
Дата: 10.01.21 10:31
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, х, Вы писали:


х>>Там можно new перекрыть в promise, чтобы оптимизировать аллокаторы.


EP>А можно было бы вообще обойтись без аллокации, так же как и для обычных лямбд/замыканий.


Да, тут согласен.

EP>И потом, даже если делать in-place аллокатор для небольших корутин — то скроей всего будет либо перерасход памяти, либо таки аллокация в куче.

Можно выделать прямо в promise. Если код наш, то ограничить размер фрейма не большая проблема. Может в следующих версиях поправят.
С уважением Вадим.
Re[7]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 10.01.21 10:46
Оценка:
Здравствуйте, х, Вы писали:

EP>>И потом, даже если делать in-place аллокатор для небольших корутин — то скроей всего будет либо перерасход памяти, либо таки аллокация в куче.

х>Можно выделать прямо в promise. Если код наш, то ограничить размер фрейма не большая проблема.

Проблема не только с размером, но и с оптимизацией как таковой. Не зная конкретного типа, в общем случае мы всегда обреченны делать runtime dispatch, так как это делает std::function. Более того, мы не можем заинлайнить весь генератор в вызывающий код в общем случае, особенно если этот генератор пришёл из вне.

х>Может в следующих версиях поправят.


Это не исправлять надо (к сожалению маловероятно что это произойдёт), а сразу надо было делать правильно, и уже были предложения как именно можно сделать оптимально. И были возражения по текущей версии, и авторам приходелось отбрехиваться мол компилятор соптимизирует аллокацию.
Отредактировано 10.01.2021 10:47 Evgeny.Panasyuk . Предыдущая версия .
Re[8]: C++20 coroutines (co_await)
От: reversecode google
Дата: 10.01.21 18:38
Оценка:
пардон, но смотря на то уродсто(пропозл) от автора асио
даже растоманы бы имели полное право плевать на С++

если сравнить то уродство с классным 6 колесным велосипедом с турбо наддувом
то ту имплементацию что добавил микрософт можно сравнить разве что с межгалактическим кораблем
до которого даже имплементации генераторов раста далеко
Re[7]: C++20 coroutines (co_await)
От: х Россия  
Дата: 11.01.21 15:10
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, х, Вы писали:


EP>Там конкретный тип promise, а не конкретной корутины. Разные корутины выдающие один и тот же promise, могут иметь разный размер, так как имеют разный размер фрейма.


size_t окружения передаётся в new.

EP>Представь что если бы у обычного замыкания, не было конкретного типа, а всегда был тип std::function

EP>
EP>std::function<void()> type_erased_labmda = [=]{ ... };
EP>

EP>И все замыкания, независимо от размера их контекста, всегда бы имели один и тот же тип.
EP>Это привело бы к неменуемым аллокациям (разные замыканиия имеют разный контекст, и соответсвенно разный размер, и поэтому все не могут быть сохранены целиком в один и тот же тип sizeof которого фиксирован), и проблемам с оптимизацией. Вот в случае с сабжем, мы именно это и получили

Витиевато ты как-то пишешь. Лучше бы не основы писал, а что предлагаешь, было бы понятнее.

EP>Проблемы с контролем времени жизни нет, даже при стирании типа — тот же std::function имеет вполне нормальное время жизни.


В корутинах есть. Ладно, сейчас не об этом.

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

EP>Когда я использую генераторы (например генератор выпрявляющий vector<vector<int>> в один range из int'ов), я хочу чтобы результат по скорости не отличался от вручную оптимизированного — zero-overhead — тоже самое что мы уже имеем с замыканиями, с сабжем так не получися, увы.

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

Давай обсуждать какие есть варианты для решения.

Допустим замена:
template<typename U>
    void await_suspend(std::experimental::coroutine_handle<U> hndl) noexcept {
      this->_future.then([hndl]() mutable {
        hndl();
      });

на
template<typename U, typename... Locals>
    void await_suspend(U hndl, Locals args...) noexcept {
      this->_future.then(hndl, std::forward<Locals>(args));

то что хочется?

В общем какое предложение?
С уважением Вадим.
Re[8]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 16.01.21 06:30
Оценка:
Здравствуйте, х, Вы писали:

EP>>Там конкретный тип promise, а не конкретной корутины. Разные корутины выдающие один и тот же promise, могут иметь разный размер, так как имеют разный размер фрейма.

х>size_t окружения передаётся в new.

Ага, в рантайме, отсюда и неизбежная аллокация в общем случае.

х>В общем по мне ты сложно как-то пишешь. Попробую моими словами. Проблемы две: 1. вынужденный new, который идёт как следствие того, что надо в фиксированный размер запихнуть нефиксированный локальный фрейм. Вторая проблема, что нельзя включить шаблонную оптимизацию.


Ну ещё проблема в том, что за счёт стирания типов, мы внезапно теряем информацию о типах, что снижает общую типизацию, и возможности по перегрузке/специализации после того как корутина уже создана.

х>Давай обсуждать какие есть варианты для решения.

х>Допустим замена:
х>
х>template<typename U, typename... Locals>
х>    void await_suspend(U hndl, Locals args...) noexcept {
      this->>_future.then(hndl, std::forward<Locals>(args));
х>

х>то что хочется?
х>В общем какое предложение?

Что-то типа, и в таком исполнении тип _future дожен зависить от конкретной корутины.

Если в общем, то например хочется чтобы вместо:
template<typename R, typename... Args> struct coroutine_traits;
Было:
template<typename ConcreteCoroutine, typename R, typename... Args> struct coroutine_traits;
Где соответвенно тип ConcreteCoroutine будет разным для:
generator<int> iota(int n);
и для
generator<int> even(int n);
Несмотря на то что у них одинаковые типы параметров и результата, потому что их локальные переменные И код могут быть разным.

Если же потребуется type-erasure (которое является нормальной техникой, у того же std::function есть вполне реальные и обоснованные варианты применения, с этим никто не спорит), то вложенные типы (::promise_type) coroutine_traits будут не зависеть от типа ConcreteCoroutine, либо зависеть но как-то выборочно (например все корутины размером до 32 байт будут давать один тип, все остальные другой, то есть тип стирается но "частично").

Но это о том как поправить вот эту вот реализацию. А принципиально проблемы нет, так как это УЖЕ работает на макросах, и вполне понятно как сделать механическую трансформацию кода из описания корутины в класс конкретного типа, собественно макросы и помогают делать эту трансформацию, конечно в меру своих ограниченных возможностей.
Отредактировано 16.01.2021 6:33 Evgeny.Panasyuk . Предыдущая версия .
Re[9]: C++20 coroutines (co_await)
От: х Россия  
Дата: 16.01.21 10:38
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ага, в рантайме, отсюда и неизбежная аллокация в общем случае.


Как минимум хотя бы одна аллокация нужна же (см. дальше).

х>>Давай обсуждать какие есть варианты для решения.

х>>Допустим замена:
х>>
х>>template<typename U, typename... Locals>
х>>    void await_suspend(U hndl, Locals args...) noexcept {
      this->>>_future.then(hndl, std::forward<Locals>(args));
х>>

х>>то что хочется?
х>>В общем какое предложение?

EP>Что-то типа, и в таком исполнении тип _future дожен зависить от конкретной корутины.


EP>Если в общем, то например хочется чтобы вместо:

EP>
EP>template<typename R, typename... Args> struct coroutine_traits;
EP>
Было:

EP>
EP>template<typename ConcreteCoroutine, typename R, typename... Args> struct coroutine_traits;
EP>
Где соответвенно тип ConcreteCoroutine будет разным для:

EP>
EP>generator<int> iota(int n);
EP>
и для

EP>
EP>generator<int> even(int n);
EP>
Несмотря на то что у них одинаковые типы параметров и результата, потому что их локальные переменные И код могут быть разным.


Хорошо, но где хранить разность (их локальные переменные)? После вызова этой функции у нас есть только generator<int>, а значит состояние самой функции где-то лежать должно. Пусть даже в упаковке для лямбды. Если ты согласен, что как минимум один new на heap нужен, то дальше можно проскипать — согласен. Но если ты можешь сказать как вообще избавиться от new — с удовольствием прочту идею.

EP>Если же потребуется type-erasure (которое является нормальной техникой, у того же std::function есть вполне реальные и обоснованные варианты применения, с этим никто не спорит), то вложенные типы (::promise_type) coroutine_traits будут не зависеть от типа ConcreteCoroutine, либо зависеть но как-то выборочно (например все корутины размером до 32 байт будут давать один тип, все остальные другой, то есть тип стирается но "частично").


Ну то есть один new для лабды ты допускаешь?
С уважением Вадим.
Re[10]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 16.01.21 17:05
Оценка:
Здравствуйте, х, Вы писали:

EP>>template<typename ConcreteCoroutine, typename R, typename... Args> struct coroutine_traits;

EP>>[/ccode]Где соответвенно тип ConcreteCoroutine будет разным для:
EP>>
EP>>generator<int> iota(int n);
EP>>
и для

EP>>
EP>>generator<int> even(int n);
EP>>
Несмотря на то что у них одинаковые типы параметров и результата, потому что их локальные переменные И код могут быть разным.

х>Хорошо, но где хранить разность (их локальные переменные)? После вызова этой функции у нас есть только generator<int>

Нет, вот тут не верно.
После вызова, у нас объект типа который определяется через corountine_traits<ConcreteCoroutine, generator<int>, int>. И этот тип может зависеть от ConcreteCoroutine, а может не зависеть — по желанию автора специализации.

х>Если ты согласен, что как минимум один new на heap нужен, то дальше можно проскипать — согласен.


Не согласен.

х>Но если ты можешь сказать как вообще избавиться от new — с удовольствием прочту идею.


Абстрагируйся от await'а, рассмотрим генератор:
generator<int> three()
{
    co_yield 1;
    co_yield 2;
    co_yield 3;
}

Возьмём простой интерфейс:
for(auto g=three(); g;)
    print(g());

Сможешь написать реализацию three вручную, удовлетворяющую этому интерфейсу и такую что программа напечатает "1\n2\n3\n"?
А без аллокаций?
А без аллокаций и без надежы на heap allocation elision optimization?

EP>>Если же потребуется type-erasure (которое является нормальной техникой, у того же std::function есть вполне реальные и обоснованные варианты применения, с этим никто не спорит), то вложенные типы (::promise_type) coroutine_traits будут не зависеть от типа ConcreteCoroutine, либо зависеть но как-то выборочно (например все корутины размером до 32 байт будут давать один тип, все остальные другой, то есть тип стирается но "частично").

х>Ну то есть один new для лабды ты допускаешь?

Я говорю что type-erasure можно получить если этого захочется из конкретного типа. Также как и можно получить std::function из конкретной лямбды.
А вот если тип уже стёрт, то обратный фокус уже не получится проделать.
Отредактировано 16.01.2021 17:06 Evgeny.Panasyuk . Предыдущая версия .
Re[11]: C++20 coroutines (co_await)
От: х Россия  
Дата: 16.01.21 19:18
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>>>template<typename ConcreteCoroutine, typename R, typename... Args> struct coroutine_traits;

EP>>>[/ccode]Где соответвенно тип ConcreteCoroutine будет разным для:
EP>>>
EP>>>generator<int> iota(int n);
EP>>>
и для

EP>>>
EP>>>generator<int> even(int n);
EP>>>
Несмотря на то что у них одинаковые типы параметров и результата, потому что их локальные переменные И код могут быть разным.

х>>Хорошо, но где хранить разность (их локальные переменные)? После вызова этой функции у нас есть только generator<int>

EP>Нет, вот тут не верно.

EP>После вызова, у нас объект типа который определяется через corountine_traits<ConcreteCoroutine, generator<int>, int>. И этот тип может зависеть от ConcreteCoroutine, а может не зависеть — по желанию автора специализации.

Так... А откуда вызывающий код знает тип ConcreteCoroutine? Конкретный тип лежит уже в реализации (.cxx файле), вызывающий код не знает какой там размер. Можно конечно через extenral const прокинуть размер объекта, но тогда ломается возможность косвенного вызова функции по указателю:

generator<int> iota(int n);
generator<int> even(int n);

generator<int> (*p)(int n) = (test ? iota : even);
(*p)(n);
С уважением Вадим.
Re[12]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 17.01.21 05:13
Оценка:
Здравствуйте, х, Вы писали:

EP>>Нет, вот тут не верно.

EP>>После вызова, у нас объект типа который определяется через corountine_traits<ConcreteCoroutine, generator<int>, int>. И этот тип может зависеть от ConcreteCoroutine, а может не зависеть — по желанию автора специализации.

х>Так... А откуда вызывающий код знает тип ConcreteCoroutine? Конкретный тип лежит уже в реализации (.cxx файле), вызывающий код не знает какой там размер.


Точно также как и с лямбдами — их код должен быть доступен, потому что по факту они определяют новый анонимный тип, то же самое и с корутинами. При этом если есть необходимость, то всегда можно стереть тип через std::function.
Также для корутин может быть автоматические послабление в зависимости от того что решит специализация corountine_traits — если тип стирается, то тело не нужно, если не стирается — то нужно. Но даже эта фича не является необходимой, так как если есть конкретный тип — легко перейти к стёртому.

Ты кстати не привёл ручную реализацию three — неужели не получается без аллокаций?
Re[13]: C++20 coroutines (co_await)
От: х Россия  
Дата: 17.01.21 07:04
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Точно также как и с лямбдами — их код должен быть доступен, потому что по факту они определяют новый анонимный тип, то же самое и с корутинами.


Ну так бы сразу и сказал, что предлагаешь инлайнить корутины. Я пас: это убьёт саму идею спрятать кишки работы с сетью и другими устройствами в корутины.

Вопросов больше нет, спасибо.
С уважением Вадим.
Re[15]: C++20 coroutines (co_await)
От: х Россия  
Дата: 17.01.21 09:06
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ну я сразу сказал что не хочу безалтернативное стирание типа.


Ты сказал что предлагаешь избавится от new, мне сдало интересно как. Много сообщений спустя я узнал как. Больше нет вопросов.


EP>1. Это, извиняюсь, откровенная чушь. Ибо возможность "прятать кишки" никуда не исчезла. Точно также как и сейчас можно сделать:

EP>
EP>std::function<int()> make();
EP>
И "спрятать кишки", в которых может быть хоть обычный тип, хоть лямбда, не смотря на то что у лямбды вполне конкретный тип и размер.


std::function<int()> приводит к new. То что корутины это просто попытка избавиться от callback hell известно.

EP>2. Корутины они не только для работы с сетью и устройствами, там действительно в большинстве случаев лишняя аллокация не так страшна. На них ещё можно делать генераторы, которые очень широко применимы И для которых эта лишняя аллокация плюс убийство инлайнинга очень сильно сужает область практического применения


Генераторы как раз можно и заинлайнить через шаблоны и лябды, что убирает new. Так что обойтись без new как раз осталась.
С уважением Вадим.
Re[16]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 17.01.21 09:19
Оценка:
Здравствуйте, х, Вы писали:

EP>>1. Это, извиняюсь, откровенная чушь. Ибо возможность "прятать кишки" никуда не исчезла. Точно также как и сейчас можно сделать:

EP>>
EP>>std::function<int()> make();
EP>>
И "спрятать кишки", в которых может быть хоть обычный тип, хоть лямбда, не смотря на то что у лямбды вполне конкретный тип и размер.

х>std::function<int()> приводит к new.

Ну так:
1. Нужно type-erasure — получите аллокацию в общем случае и отсутсвие инлайнинга.
2. Не нужно — используйте конкретный тип и покажите его определение.

В том что я предлагаю доступно и 1. и 2., на выбор. То есть можно либо "спрятать кишки", либо "показать", в зависимости от хотелок, точно также как и с лямбдами.
В том что имеем в стандарте — всегда получаем стирание типа, плюс сказки про heap allocation elision optimization

EP>>2. Корутины они не только для работы с сетью и устройствами, там действительно в большинстве случаев лишняя аллокация не так страшна. На них ещё можно делать генераторы, которые очень широко применимы И для которых эта лишняя аллокация плюс убийство инлайнинга очень сильно сужает область практического применения

х>Генераторы как раз можно и заинлайнить через шаблоны и лябды, что убирает new. Так что обойтись без new как раз осталась.

Каким образом сделать это в общем случае? Там результирующий тип чисто по-построению зависит только от типов параметров и типа резултата, и не зависит от конкретной реализации.
Это точно также как если в std::for_each передавать указатель на функцию — инстанцияция std::for_each будет одна на каждый тип указателей на функцию. В некоторых частных случаях этого можно соптимизировать сделав больше инлайнига, но в общем случае это чисто технически невозможно, например если указатель на функцию сохранён в поле класса. В то же время если передавать лямбду — то каждая лямбда будет пораждать разную инстанцияцию std::for_each, на порядки облегчая работу оптимизатора.
Отредактировано 17.01.2021 9:23 Evgeny.Panasyuk . Предыдущая версия .
Re[17]: C++20 coroutines (co_await)
От: х Россия  
Дата: 17.01.21 10:00
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ну так:

EP>1. Нужно type-erasure — получите аллокацию в общем случае и отсутсвие инлайнинга.
EP>2. Не нужно — используйте конкретный тип и покажите его определение.

Так если хочешь инлайны, то бери шаблоны и лябды — ноль аллокаций и всё быстро. Зачем для этого новая сущность? Корутины ввели для облегчения callback hell — и именно эту проблему они решают хорошо.
С уважением Вадим.
Re[18]: C++20 coroutines (co_await)
От: Evgeny.Panasyuk Россия  
Дата: 17.01.21 11:26
Оценка:
Здравствуйте, х, Вы писали:

EP>>Ну так:

EP>>1. Нужно type-erasure — получите аллокацию в общем случае и отсутсвие инлайнинга.
EP>>2. Не нужно — используйте конкретный тип и покажите его определение.
х>Так если хочешь инлайны, то бери шаблоны и лябды — ноль аллокаций и всё быстро. Зачем для этого новая сущность? Корутины ввели для облегчения callback hell — и именно эту проблему они решают хорошо.

Корутины позволяют автоматически нарезать функцию на продолжения, значительно сокращая и распутывая зашумлённый код. Два самых крупных применения этому — генераторы и await, есть и другие.
Соответсвенно в том же C#, или даже Python — они также присутсвуют и в виде yield, и в виде await, так как обе фичи являются реально полезными. Даже в функциональных языках это доступно в виде более общей концепции монад.
И даже в новом стандарте C++ — есть и co_yield и co_await. То есть корутины помогают решать задачи в самых разных областях. Правильно реализованные stackless корутины, с поддержкой перемещения, копирования и рефлексированния контекста, покрыли бы ещё большой класс задач решаемых монадами.
Ты судя по-всему, осведомлён только об одном каком-то специфичном use-case'е, близком к твоей прикладной области, и проецируешь частные требования на все корутины, что никак недопустимо говоря о языке с таким широким применением как C++
Твоё предложение использовать шаблоны и лямбды вместо корутин — абсурдно, ибо означает "нарезай код на продолжения вручную" и проблему распутывания кода никак не решает, а по сути отрицает

В целом даже непонятно с чем ты споришь, ибо возвможность доступа к конкретному типы корутины была бы крайне полезна для одних use-case'ов, и не мешала бы остальным, так как при необходимости тип элементарно стирается. win-win. Хочешь слепо защищать авторов этого конкретного proposal — ну удачи
Re[2]: C++20 coroutines (co_await)
От: gwg-605 Россия  
Дата: 16.04.21 16:45
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

O>>корутины.


ЕМ>Отчего эта корявая калька так расплодилась в народе? Есть же (еще с середины прошлого века) отличный термин — сопрограммы. Прям тест на знание истории программирования.

Термины это всегда боль Мое представление, что указанные coroutine
1. никакого отношения с многозадачности не имеют, и достаточно легки для понимания (функция со стейтом или стейт машина над кусками кода). Для примера вот объяснение здесь
2. на них можно натянуть многозадачность также как и на все другое, и вот здесь начинается основные вопросы...

ЗЫ. Я честно говоря сам пока не разобрался со всей этой фигней очень не хочется лезть в стандарт, надеюсь, что кто-то уже разжевал, и может внятно объяснить как это работает
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.