C++1z Coroutines - языковая функция?

Почему сопрограммы (на данный момент в новейших черновиках для C++1z) будут реализованы как основная языковая функция (причудливые ключевые слова и все такое), а не как расширение библиотеки?

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

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

Так есть ли веская причина для этого? Каковы преимущества?


person Lazarus535    schedule 31.01.2016    source источник
comment
Я не знаю, как работает boost:coroutines и предлагают ли они одинаковую семантику, но я предполагаю, что сопрограммы могут быть реализованы гораздо эффективнее как функция языка, чем функция библиотеки. Кроме того, я не совсем уверен, что сопрограммы вообще могут быть реализованы с использованием только стандартного С++.   -  person MikeMB    schedule 01.02.2016
comment
@MikeMB: правильно во всех учетных записях.   -  person ildjarn    schedule 01.02.2016
comment
Другая причина может заключаться в том, что это просто лучше как часть языка (например, не нужно включать специальные заголовки или передавать специальные типы в качестве параметров в функции).   -  person RamblingMad    schedule 01.02.2016
comment
Я считаю, что аргумент Гора Нишанова из Microsoft заключается в том, что в качестве функции компилятора он генерирует меньше кода/более эффективен. По сути, в своем видео (ссылка на мой ответ) он рассказывает о том, как на самом деле они обобщают функции, так что они могут возвращаться раньше. Он также дает некоторые показатели производительности в видео. Переключение контекста приведет к промаху кеша, но для сетевого кода это, вероятно, не имеет значения.   -  person Atifm    schedule 16.08.2016


Ответы (3)


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

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

person Dietmar Kühl    schedule 01.02.2016
comment
Сопрограммы Boost основаны на другой библиотеке: Boost Context, которая предлагает особенности платформы переключения контекста. Насколько я понимаю, для этого используется некоторый взлом сборки. Но я не думаю, что есть проблема с локальными переменными. Они просто остаются в стеке после переключения контекста. - person Lazarus535; 01.02.2016
comment
@ Lazarus535: этот подход работает для стековых сопрограмм. Существуют также бесстековые сопрограммы, которым необходимо хранить используемые переменные в другом месте. Бесстековые сопрограммы в Boost используют макрос-хак (по сути, разновидность Duff's Device) вместе с обязательным базовым классом для соответствующего состояния. Сопрограммы без стеков намного эффективнее, чем сопрограммы с стеками, в обмен на определенные ограничения. - person Dietmar Kühl; 01.02.2016

На CppCon 2015 Гор Нишанов из Microsoft привел аргумент, что корутины C++ могут быть отрицательной абстракцией накладных расходов. Документ из его выступления: здесь.

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

У них есть первоначальная реализация в Visual Studio 2015, поэтому вы можете попробовать ее для своего варианта использования и посмотреть, как она сравнивается с реализацией boost. Похоже, они все еще пытаются выяснить, будут ли они использовать ключевые слова Async/Yield, поэтому следите за тем, куда идет стандарт.

Предложение по возобновляемым функциям для C++ можно найти здесь и обновление здесь. К сожалению, она не вошла в c++17, но теперь является технической спецификацией p0057r2. С другой стороны, похоже, что они поддерживаются в clang с флагом -fcoroutines_ts и в Visual Studio 2015 Update 2. К ключевым словам также добавляется co_. Итак, co_await, co_yield и т. д.

Сопрограммы — это встроенная функция в golang, D, python, C#, и она войдет в новый стандарт Javascript (ECMA6). Если C++ предложит более эффективную реализацию, интересно, вытеснит ли она использование golang.

person Atifm    schedule 09.02.2016

возобновляемые функции из C++1z поддерживают переключение контекста без стека, а boost.coroutine(2) обеспечивает переключение контекста с полным стеком.

Разница заключается в том, что при переключении контекста в стеке кадры стека функции, вызываемой внутри сопрограммы, остаются нетронутыми при приостановке контекста, в то время как кадры стека подпрограмм удаляются при приостановке возобновляемой функции (C++1z).

person xlrg    schedule 15.02.2016