[trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk  
Дата: 03.07.13 14:59
Оценка: 64 (6)
Эмуляция оператора await из языка C# 5.
Данный proof-of-concept показывает, что идентичный синтаксис оператора await может быть достигнут с помощью Stackful Coroutines, демонстрируя что они предоставляют превосходящие возможности.
Цель данного proof-of-concept — привлечь внимание к Stackful Coroutines, а не эмуляция await'а сама по себе — так как с помощью сопроцедур можно достичь более высоких уровней инкапсуляции
Автор: Evgeny.Panasyuk
Дата: 21.06.13
.
Пример использования:

int bar(int i) { // await is not limited by "one level" as in C# auto result = await async([i]{ return reschedule(), i*100; }); return result + i*10; } int foo(int i) { cout << i << ":\tbegin" << endl; cout << await async([i]{ return reschedule(), i*10; }) << ":\tbody" << endl; cout << bar(i) << ":\tend" << endl; return i*1000; } void async_user_handler() { vector<future<int>> fs; // instead of `async` at function signature, `asynchronous` should be // used at the call place: for(auto i=0; i!=5; ++i) fs.push_back( asynchronous([i]{ return foo(i+1); }) ); for(auto &&f : fs) cout << await f << ":\tafter end" << endl; }


"Оператор" await принимает std::future-like объект с поддержкой продолжений (например .then) и возвращает результат future (await future<int>(...), вернёт int).
В данном примере используется boost::async. Но такой подход может использоваться и с другими видами future, например PPL task::then и т.д.
Вывод:

1: begin 2: begin 3: begin 4: begin 5: begin 20: body 10: body 30: body 110: end 1000: after end 50: body 220: end 2000: after end 550: end 40: body 330: end 3000: after end 440: end 4000: after end 5000: after end


Re: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Шахтер  
Дата: 03.07.13 18:01
Оценка: +3 -2
Здравствуйте, Evgeny.Panasyuk, Вы писали:

Я вот лет 10 назад экспериментировал с корутинами. Сделал реализацию под студию. Насколько я понимаю, аналогичная реализация сейчас добавлена в boost.
И так с тех пор она мне не пригодилась. Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки,
а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.
В XXI век с CCore.

Копай Нео, копай -- летать научишься. © Matrix. Парадоксы

Re[2]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk  
Дата: 03.07.13 19:41
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки,

Ш>а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.

А тут дело не только в псевдо/green-потоках.
Весь шум из-за того, что await это один из способов распрямить код использующий результаты "асинхронных" вызовов без блокирования вызывающего потока, сделать implicit continuations. Сами вызовы необязательно выполняются в одном потоке — в примере выше по async может использоваться пул реальных потоков.

Саттер, в последнем выступлении на C9, показывал примеры асинхронного кода WinRT и сказал что возможно в C++ добавят await.
Я не то чтобы совсем против await'а, но я в первую очередь предпочту сначала нормальные stackful coroutines — они намного мощнее await'а и как показывает пример выше на них можно легко реализовать как await-like код (для чего собственно я и сделал proof-of-concept), так и много чего другого.
Во-вторых, имхо, добавить stackful coroutines в ISO будет легче, чем await. В Boost.Coroutine сейчас довольно лаконичный интерфейс. А функции с await наверняка будут иметь много ограничений, либо спецификация будет громоздкой (C++ это всё-таки не C#).
Re[2]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: enji  
Дата: 04.07.13 08:10
Оценка: +1
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, Evgeny.Panasyuk, Вы писали:


Ш>Я вот лет 10 назад экспериментировал с корутинами. Сделал реализацию под студию. Насколько я понимаю, аналогичная реализация сейчас добавлена в boost.

Ш>И так с тех пор она мне не пригодилась. Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки,
Ш>а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.

В настоящей многопоточности нужна синхронизация, а в корутинах с этим все проще.
Так что если задача позволяет — часто корутины удобнее...
Re: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Abyx Россия http://tinyurl.com/We-Do-Not-Jump
Дата: 04.07.13 08:57
Оценка: -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Эмуляция оператора await из языка C# 5.

EP>Данный proof-of-concept показывает, что идентичный синтаксис оператора await может быть достигнут с помощью Stackful Coroutines, демонстрируя что они предоставляют превосходящие возможности.
EP>Цель данного proof-of-concept — привлечь внимание к Stackful Coroutines, а не эмуляция await'а сама по себе — так как с помощью сопроцедур можно достичь более высоких уровней инкапсуляции
Автор: Evgeny.Panasyuk
Дата: 21.06.13
.


у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines.
т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент".
In Zen We Trust
Re[2]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk  
Дата: 04.07.13 10:35
Оценка: 3 (1) +1
Здравствуйте, Abyx, Вы писали:

A>у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines.

A>т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент".

Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Шахтер  
Дата: 04.07.13 15:49
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.
В XXI век с CCore.

Копай Нео, копай -- летать научишься. © Matrix. Парадоксы

Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Шахтер  
Дата: 04.07.13 15:53
Оценка:
Здравствуйте, enji, Вы писали:

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


Ш>>Здравствуйте, Evgeny.Panasyuk, Вы писали:


Ш>>Я вот лет 10 назад экспериментировал с корутинами. Сделал реализацию под студию. Насколько я понимаю, аналогичная реализация сейчас добавлена в boost.

Ш>>И так с тех пор она мне не пригодилась. Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки,
Ш>>а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.

E>В настоящей многопоточности нужна синхронизация, а в корутинах с этим все проще.


Есть такое. Просто корутины передают управление в фиксированных точках, что упрощает многие вещи.

E>Так что если задача позволяет — часто корутины удобнее...


Зато потоки обеспечат выигрыш в производительности.
В XXI век с CCore.

Копай Нео, копай -- летать научишься. © Matrix. Парадоксы

Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: enji  
Дата: 04.07.13 16:26
Оценка:
Здравствуйте, Шахтер, Вы писали:

E>>Так что если задача позволяет — часто корутины удобнее...


Ш>Зато потоки обеспечат выигрыш в производительности.


С этим я не спорю
Лично у меня специфика такова, что задачи зависят в основном от скорости обмена по сети или по последовательному порту. А для таких случаев удобно большую часть задач крутить в одном потоке, а чтобы писать нормальный код в таком стиле и используются корутины.
Re: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: night beast  
Дата: 05.07.13 17:29
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Эмуляция оператора await из языка C# 5.

EP>Данный proof-of-concept показывает, что идентичный синтаксис оператора await может быть достигнут с помощью Stackful Coroutines, демонстрируя что они предоставляют превосходящие возможности.
EP>Цель данного proof-of-concept — привлечь внимание к Stackful Coroutines, а не эмуляция await'а сама по себе — так как с помощью сопроцедур можно достичь более высоких уровней инкапсуляции
Автор: Evgeny.Panasyuk
Дата: 21.06.13
.


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

Re[2]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk  
Дата: 06.07.13 05:37
Оценка: +1
Здравствуйте, night beast, Вы писали:

NB>честно говоря, поражаюсь вашему терпению.

NB>сам бы уже несколько раз бросил что-либо доказывать упертым шарперам
NB>

Не, это совсем не из-за "упёртых шарперов" — я в той теме даже не показывал
Я сделал этот прототип, сразу после того как посмотрел презентацию Саттера. Он рассказал, о том, что возможно в C++ добавят await. Я же предпочту сначала увидеть Stackful Coroutines в ISO, так как они более мощные, поэтому и сделал пример.
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk  
Дата: 04.10.13 17:58
Оценка: 61 (7)
EP>Я сделал этот прототип, сразу после того как посмотрел презентацию Саттера. Он рассказал, о том, что возможно в C++ добавят await. Я же предпочту сначала увидеть Stackful Coroutines в ISO, так как они более мощные, поэтому и сделал пример.

Этот прототип теперь используется в N3708 "A proposal to add coroutines to the C standard library" как пример (page 5)
Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: koodeer  
Дата: 04.10.13 20:12
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.


Это является и достоинством, и недостатком одновременно. Тем и плох C++, что почти всё можно сделать слишком большим количество разных способов. Это усложняет поддержку проектов, усложняет вхождение в проект новых людей.
Вон в C# способов раз-два и обчёлся. Зато даже джуниоры знают (ну или считают, что знают) async/await.
Re[5]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: jazzer Россия Skype: enerjazzer
Дата: 04.10.13 20:27
Оценка:
Здравствуйте, koodeer, Вы писали:

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


Ш>>Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.


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

K>Вон в C# способов раз-два и обчёлся. Зато даже джуниоры знают (ну или считают, что знают) async/await.

Ну так С++ и не позиционировался никогда как дружественный к новичкам. У него несколько другие приоритеты

jazzer (Skype: enerjazzer) You will always get what you always got If you always do what you always did

Re[5]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: zaufi  
Дата: 04.10.13 20:29
Оценка:
Здравствуйте, koodeer, Вы писали:

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


Ш>>Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.


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


что-то на вхождение в Perl или там Python это не особо влияет я смотрю %) да и жалоб со от разработчиков что-то не слышно (в основном "нытье" от тех кто изучает).
Perl я могу читать только простой код, а вот на Python доводилось кодить разного... по количеству способов сделать одно и тоже С++ до него как ... ну вы поняли...

K>Вон в C# способов раз-два и обчёлся. Зато даже джуниоры знают (ну или считают, что знают) async/await.
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Ikemefula Беларусь  
Дата: 04.10.13 20:48
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

A>>у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines.

A>>т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент".

EP>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).


200К которые счетчик инкрементили или это был сервер простецкий ?
Re[6]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: jazzer Россия Skype: enerjazzer
Дата: 04.10.13 20:50
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>что-то на вхождение в Perl или там Python это не особо влияет я смотрю %) да и жалоб со от разработчиков что-то не слышно (в основном "нытье" от тех кто изучает).

Z>Perl я могу читать только простой код, а вот на Python доводилось кодить разного... по количеству способов сделать одно и тоже С++ до него как ... ну вы поняли...

И это при том, что Питон именно в этом

There should be one — and preferably only one — obvious way to do it.

объявил священную войну Перлу,
  который на самом деле проповедует вот что

Just because you CAN do something a particular way doesn't mean that you SHOULD do it that way. Perl is designed to give you several ways to do anything, so consider picking the most readable one.


но кого это волнует


ЗюЫю Кстати, я недавно натолкнулся на явную поддержку в Перле оптимизации хвостовой рекурсии — был приятно удивлен

jazzer (Skype: enerjazzer) You will always get what you always got If you always do what you always did

Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Ikemefula Беларусь  
Дата: 04.10.13 21:05
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


NB>>честно говоря, поражаюсь вашему терпению.

NB>>сам бы уже несколько раз бросил что-либо доказывать упертым шарперам
NB>>

EP>Не, это совсем не из-за "упёртых шарперов" — я в той теме даже не показывал

EP>Я сделал этот прототип, сразу после того как посмотрел презентацию Саттера. Он рассказал, о том, что возможно в C++ добавят await. Я же предпочту сначала увидеть Stackful Coroutines в ISO, так как они более мощные, поэтому и сделал пример.

Stackfull точно не будет. Судя по голосовалке на этом сайте файберы использовало ажно 7% программистов и это при том, что голосовалка была создана ажно в 2005м, когда местные сиплюсники еще боялись признаться, что они уже дотнетчики
Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk  
Дата: 05.10.13 12:14
Оценка:
Здравствуйте, Ikemefula, Вы писали:

A>>>у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines.

A>>>т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент".
EP>>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).
I>200К которые счетчик инкрементили или это был сервер простецкий ?

while(true) { ++counter; yield(); }

Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
От: Evgeny.Panasyuk  
Дата: 05.10.13 12:23
Оценка:
I>Stackfull точно не будет.

Не вижу принципиальных преград. Например в D есть fiber'ы.

I>Судя по голосовалке на этом сайте файберы использовало ажно 7% программистов


7% от чего? Какой вопрос был?
Я, например, сильно сомневаюсь что хотя бы 7% от всех C#'еров использует await, или даже yield.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.