What is the difference between asymmetric and symmetric coroutines?

I noticed that support for symmetric coroutines was removed in Boost.Coroutine2 for C ++, so I wanted to understand what is the difference between the two?

+5
source share
2 answers

The distinction between symmetric and asymmetric coroutines is especially well described by Ana Lucia de Moura and Roberto Ierasulsky in his article " Revisiting Coroutines :

The well-known coroutine classification refers to the transmission control operations that are provided, and distinguishes between symmetric and asymmetric coroutines. Symmetric coprocessors provide a single control transfer operation that allows coroutines to explicitly transfer control to each other. Asymmetric accompanying mechanisms (more commonly referred to as semi-symmetric or half-short) provide two control transfer operations: one to call the coroutine and one to suspend it, the latter returning control to the calling coprocessor. Although symmetric coroutines work at the same hierarchical level, an asymmetric coroutine can be considered subordinate to its calling party, and the relationship between them is somewhat similar to the connection between the called and calling procedure.

Coroutine concurrent programming mechanisms typically provide symmetric coroutines to represent independent execution units, as in Modula-2. On the other hand, coprocessor mechanisms designed to implement constructs that generate sequences of values ​​typically provide asymmetric coroutines. Examples of this type of construction are iterators and generators.

(Quotes omitted)

In an asymmetric co-process model, β€œasymmetry” refers to the fact that there is a relationship between callers between stack type callers. The command line can either call another coroutine or pause it, gaining control over its caller, as a rule, at the same time gives value to the caller.

In a symmetric co-process model, a coroutine can give control over any other coroutine without restriction.

Two models actually have the same expressive power; that is, asymmetric coroutines can be implemented using symmetric coroutines and vice versa. (See Symmetric coroutines written by Giovanni P. Deretta for a transformation between the two types of coroutines.) Therefore, Mura and Irusalimsky write: Providing both constructs only complicates the semantics of the coroutine mechanism without increasing its expressive power. "

Coroutine2 developers decided not to provide symmetric coroutines in the library, because they believe that the symmetric coroutine functionality is better implemented boost::context::execution_context (part of Boost.Context): http://lists.boost.org/Archives/boost/2015 /06/223701.php

+6
source

Coroutines switch between caller and callee, for example. you enter the corotuine function and return back to the calling code. Typically (asymmetric) coroutines have two functions for this purpose:

  • Caller Summary Function
  • suspend function called inside a coroutine

Since you have two functions to switch context, this is called asymmetric. Symmetric coroutines have only one function, which pauses the current context and resumes another. Note that you need to specify which symmetric coroutine should be continued as follows.

Symmetric coroutines can be used to implement user land flows (a symmetric coroutine represents a user flow, the scheduler jumps from one to the next symmetric coroutine, for example, the next user land flow is planned) more efficiently than asymmetric coroutines. This is obvious because symmetric coroutines do not need to return to the caller to resume the next stream of user land. Asymmetric coroutines require more context switches than symmetric coroutines to achieve the same functionality.

Symmetric coroutines - symmetric context switching - are better represented by concepts such as β€œ call with current continuation ” (Scheme, Ruby ...). boost.context supports this concept with its implementation of callcc () / continue . Therefore, boost.coroutine2 does not provide a symmetric coroutine coprocessor, but the asymmetric boost.coroutine2 coprocessor is implemented with boost.context callcc () / continued .

+4
source

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


All Articles