2016-01-31 12 views
6

Perché le coroutine (come da ora nelle bozze più recenti per C++ 1z) devono essere implementate come funzionalità linguistica di base (parole chiave elaborate e tutte) anziché un'estensione di libreria?C++ 1z Coroutine una lingua?

Esiste già un paio di implementazioni (Boost.Coroutine, ecc.), Alcune delle quali possono essere rese indipendenti dalla piattaforma, da ciò che ho letto. Perché il comitato ha deciso di utilizzarlo nel linguaggio di base?

Non sto dicendo che non dovrebbero, ma lo stesso Bjarne Stroustrup menziona in alcuni discorsi (non so più quale altro) che le nuove funzionalità dovrebbero essere implementate nelle biblioteche il più possibile invece di toccare il linguaggio principale.

Quindi c'è una buona ragione per farlo? Quali sono i vantaggi?

+3

Non so come aumentare: le coroutine funzionano e se offrono la stessa semantica, ma la mia ipotesi è che le coroutine possano essere implementate in modo molto più efficiente come funzionalità di una lingua rispetto a una funzione di libreria. Inoltre, non sono del tutto sicuro se le coroutine possano effettivamente essere implementate usando solo il C++ standard. – MikeMB

+0

@MikeMB: corretto su tutti gli account. – ildjarn

+1

Un altro motivo potrebbe essere che è semplicemente molto più bello come parte della lingua (ad esempio non dover includere intestazioni speciali o passare tipi speciali come parametri alle funzioni) – CoffeeandCode

risposta

7

Mentre esistono implementazioni di libreria di coroutine, queste tendono ad avere restrizioni specifiche. Ad esempio, un'implementazione di libreria non può rilevare quali variabili devono essere mantenute quando una coroutine viene sospesa. È possibile aggirare questa necessità, ad es. Rendendo esplicite le variabili utilizzate in qualche modo. Tuttavia, quando le coroutine dovrebbero comportarsi il più possibile come normali funzioni, dovrebbe essere possibile definire variabili locali.

Non credo che nessuno degli implementatori delle coroutine di Boost ritenga che la loro rispettiva interfaccia di libreria sia l'ideale. Mentre è il migliore che può essere raggiunto nella lingua corrente, l'uso generale può essere migliorato.

+2

Le coroutine più potenti si basano su un'altra libreria: Boost Context, che offre le specifiche della piattaforma per il cambio di contesto. Da quello che ho capito, c'è un po 'di hacking di assemblaggio coinvolto nel far sì che ciò accada. Ma non penso che ci sia un problema con le variabili locali. Rimangono semplicemente in pila dopo un cambio di contesto. – Lazarus535

+2

@ Lazarus535: questo approccio funziona con coroutine di stacking. Ci sono anche coroutine senza stack che devono memorizzare le variabili utilizzate altrove. Le coroutine prive di stack in Boost utilizzano una macro hack (essenzialmente una variante di [Duff's Device] (https://en.wikipedia.org/wiki/Duff%27s_device)) insieme a una classe di base obbligatoria per lo stato pertinente. Le coroutine prive di pila sono molto più efficienti delle coroutine impilate - in cambio di determinati vincoli. –

4

A CppCon 2015, Gor Nishanov di Microsoft ha sostenuto che C++ Coroutine può essere a negative overhead abstraction. Il documento del suo intervento è here.

Se si dà un'occhiata al suo esempio, la possibilità di utilizzare una coroutine ha semplificato il flusso di controllo del codice di rete e, se implementato a livello di compilatore, fornisce un codice più piccolo che ha il doppio della velocità dell'originale. Egli sostiene che la capacità di cedere in realtà dovrebbe essere una caratteristica di una funzione C++.

Hanno un'implementazione iniziale in Visual Studio 2015, quindi puoi provarlo per il tuo caso d'uso e vedere come si confronta con l'implementazione boost. Sembra che stiano ancora cercando di cancellare se useranno le parole chiave Async/Yield, quindi tieni d'occhio dove va lo standard.

La proposta di funzioni di riprendere per C++ può essere trovata here e l'aggiornamento here. Sfortunatamente, non è diventato in C++ 17, ma ora è una specifica tecnica p0057r2. Sul lato positivo, sembra che il loro sia il supporto in clang con il flag -fcoroutines_ts e in Visual Studio 2015 Update 2. Le parole chiave hanno anche un co_ anteposto a loro. Quindi co_await, co_yield ecc.

Le coroutine sono una funzionalità incorporata in golang, D, python, C# e saranno nel nuovo standard Javascript (ECMA6). Se C++ si presenta con un'implementazione più efficiente, mi chiedo se sostituirà l'adozione di golang.

2

le funzioni di ripristino da C++ 1z supportano la commutazione di contesto senza stack, mentre boost.coroutine (2) fornisce la commutazione di contesto stackfull.

La differenza è che con il cambio di contesto impilabile i frame di stack della funzione chiamata all'interno della coroutine rimangono intatti a sospendere il contesto, mentre i frame di stack dei sub-routien vengono rimossi sospendendo una fucilazione ripristinabile (C++ 1z).