📜 ⬆️ ⬇️

Objection to making Coroutines with await in C ++ 17

Recently, a group of C ++ experts participating in the work of the standardization committee visited Russia. On February 25, they participated in a Q & A session organized by Yandex, and then spoke at the C ++ Russia 2016 conference. One of them was Gor Nishanov, the author of the proposal to include C # -like coroutines (those that are async / await) in C ++ standard 17 . Earlier, Gore spoke at CppCon 2015 with the report " C ++ Cosprograms - Abstraction with a negative overhead projector ." Such an opportunity to structure an asynchronous code looks attractive, Gore in the report convincingly shows that the amount of code is reduced, and the speed of work increases compared to the “handwritten” State Machine. In addition, this is one of the biggest potential changes in the next standard and attracts attention. Judging by the publications, the proposal has received significant approval and the committee is inclined to be included in the standard.

After that, I was quite surprised when I mentioned the proposal P0057 , having received the counter-document " Coroutines doesn’t belong to TS ", which subjects the proposed implementation of coroutines to harsh and very emotional criticism and demands not to be included in C ++ 17, but to put off for " running in "Technical Specification. I note that I am not a supporter of these objections, but I invite those interested to discuss how justified these claims are and whether everything is so bad. Under the cut "squeeze" of the document with a few comments.

The first thing to notice: one of the opponents is Christopher Kohlhoff, the author and maintainer Boost.Asio, who can be considered a specialist in asynchronous programming. Then striking the sharp and emotional tone of the document. Not just minor remarks, but a fundamental disagreement. I will cite a few quotes:

The sentence seems to be copying from other languages, but not learning from the mistakes they made. We should not blindly copy these errors in C ++.
')
... the desire to include in the C ++ 17 such a proposal and a hasty and stupid.

Considering that we have a chance to become one of the first languages ​​in which this is implemented correctly, I am surprised that we are in a hurry to standardize a non-optimal, I would even say, broken approach.

There are two big red flags that people ignore in their desire to add a “big ticket” and a “cool” feature in C ++ 17.


So, what claims are presented:

1) The most important point: the need to use the await keyword to mark asynchronous calls on which suspend occurs. This model is called by the authors of the document “suspend-up” and lists the following disadvantages:


This model, the authors oppose the so-called "suspend-down" model, which is not invasive and is used in Boost.Coroutines. She was also proposed to the committee, “Resumable Expression” by Christopher Kohlhoff, but preference was given to C # -like await.
The difference with this model is that it is not necessary to mark asynchronous calls with the word await. An entity is called that “looks like a normal function from the outside,” for example, suspend (). It internally performs a context switch (Boost.Coroutines uses Boost.Context) without exiting the caller and “hanging” the entire call stack until the asynchronous operation is completed. In this case, the first functions in the chain may even “not know” that they cause an asynchronous operation, and no modification of the existing code is required.

Gor Nishanov answered the following on this topic (video of the report on CppCon, Q & A in Yandex):


2) The following is what the authors of the document indicate: when designing coroutines, much of the experience and use-cases for platforms that require a short response time were ignored. For example, are systems for financial markets. It is stated that the operation of such systems is regulated by laws, and the refusal may entail investigation and prosecution.
For this reason, a mental experiment is not suitable and coroutines must be pre-tested in work in such areas.

3) Next comes an interesting “clash of the worlds” argument: Linux is the most common platform for high-performance systems, so a test implementation of coroutines for MSVC / Windows does little to measure performance.

4) C-routines in the style of C # await - largely the result of simply copying syntax from other languages. Copied and launched into work. At the same time, the errors and shortcomings of the coroutines from these languages ​​(C #, Python) were copied.

In addition, the coroutine model was largely borrowed from dynamic languages. And it is very likely that it is not optimal and can be done better for C ++.

5) Security and performance risks: the current design of coroutines increases the risk of jitter, lack of resources for individual tasks (starvation) and DOS attacks. One of the reasons is that coroutines use cooperative multitasking, not preemptive. Therefore, with a small number of threads, one coroutine can capture resources for a long time and the OS scheduler will not come to the rescue.

To be honest, this item seemed to me somewhat attracted. In any case, some implementation details can be corrected and the fundamental flaws inherent in the model are not visible.

6) Risk for correctness: after completing an asynchronous operation, the coroutine can be continued on another stream. The authors believe that this behavior is valid, but it should not be the default.

At the same time, this problem is perfectly solved in C # await. If an operation is launched from a UI stream, then continuation is always invoked in the UI thread too.

7) The risk that if an await (suspend-up) model is adopted, this will complicate the inclusion of models in the standard suspend-down model (modeled on Boost.Corountines). It will be difficult to convince the standardization committee to waste time on the functionality that “already is”.

If the proposed await coroutines were only implemented at the library level, this would leave room for maneuver and research on alternatives. But in the current form there may be no way back.

suggestions



1) Defer the inclusion of coroutines in C ++ 17 and include for the time being in the Technical Specification for “running in”.

2) Continue work on the suspend-down model and perhaps form two proposals for coroutines into the future standards Suspend-Up Coroutines and Suspend-Down Coroutines.

3) The current coroutine proposal was largely advantageous because Gor Nishanov had the opportunity to experiment and refine the Visual Studio compiler at Microsoft. Therefore, the authors of the alternative coroutry model expect cooperation with the developers of GCC and Clang to refine and experiment on high-loaded Linux systems.

Conclusion



In conclusion, the authors mention that there are two “big red flags”:

1) Those committee members who have extensive experience in using coroutines in high-load systems have little effect for various reasons.

2) Currently there are several proposals in the Technical Specification: Parallelism, Concurrency, Networking and potentially “Suspend-Up Coroutines” and “Suspend-Down Coroutines”, which require a single and consistent model or at least a thoughtful interaction.

Therefore, you need time and rush with coroutines is not worth it.

What is your opinion? How critical are these disadvantages?
And is it worth postponing coroutines to later include two varieties in the standard at once?

UPD : in the comments Mikanor gives a link to the article " resumable functions - async and await " in the blog Meeting C ++ from 2013. It describes in some detail the initial idea and advantages of coroutines with await.
On Habré there was a translation of this article from tangro and discussion.

UPD2 : Let me remind you that this article is not a complete translation of the document “Coroutines belong in a TS”, but rather a digest designed to draw attention to an alternative point of view on coroutines with await (especially suspend-up vs suspend-down). Details and detailed description of each item can be found in the original document .

Source: https://habr.com/ru/post/278267/


All Articles