7 ms·
LLVM Coroutines - This is the most exciting thing for me. Gor Nishanov in his videos explains how coroutines are implemented and how are optimized by LLVM. Asyn
by lossolo 10y ago
LLVM Coroutines - This is the most exciting thing for me. Gor Nishanov in his videos explains how coroutines are implemented and how are optimized by LLVM. Asynchronous IO code will be so easy to write and so efficient.
Context switch in cost of function call, you can have billions of those coroutines, heap allocation elision (in certain cases). Can't wait for coroutines to land in Clang.
I am a big fan of Go gorutines so Networking TS and Coroutines TS made me very happy, connecting both and having it in standard will be great. Just a shame that for Networking TS integration we will need to wait for C++20.
- richdougherty 10y agoHere's the documentation: http://llvm.org/docs/Coroutines.html http://llvm.org/docs/Coroutines.html
- astrodust 10y agoIs this similar to fibers?
- lngnmn 10y agoIt would be interesting to try these in some functional language backend, say, in GHC or Ocaml.
- mhh__ 10y agoGHC compiles haskell through about a million different IRs and abstract machines, until eventually reaching Cmm, which is effectively a similar idea to LLVM IR (A very simple C ish imperative language). Any benefits to be had, should be fairly straightforward for the GHC folks to use, which should be cool.
- kccqzy 10y agoIt's just Core, STG, Cmm. Anything else I'm missing?
- mrkgnao 10y agoNo. But that is probably two more than most other languages with a similar compilation model. (I think Rust has two IRs?)
- mhh__ 10y agoI wasn't trying to be critical, it's just significantly more than most languages (With good reason!). This is a good thing, I dream of when we will have libraries/frameworks for doing these kind of high level program transformations in a modular way a la LLVM.
- wahern 10y agoGo-style coroutines will still be more efficient and more elegant than C++ coroutines. Goroutines are stackful, whereas in C++ you'll need to manually chain coroutines. That means a dynamic allocation and deallocation for _each_ call frame in the chain. That's more efficient than JavaScript-style continuation closures, but in many situations still far more work than would be required for stackful coroutines. Everything described in Gor Nishanov's video applies equally to stackful vs non-stackful coroutines. That is, the code conciseness, composability, and performance advantages of non-stackful coroutines are even greater with stackful coroutines. Nishanov dismisses stackful coroutines out-of-hand because to be memory efficient one would need relocatable (i.e. growable) stacks. But that begs the question of how costly it would be to actually make the stack relocatable. I would assume that in a language like C++ where stack layout must already be recorded in detail to support exceptions, that efficiently relocatable stacks wouldn't be too difficult to implement. At the end of the day, without stackful coroutines networking still won't be as elegant as in Go. And for maximum performance, state machines (e.g. using computed gotos) will still be useful. You'll either need to sacrifice code clarity and composition by explicitly minimizing chains, or you'll sacrifice performance by having deep coroutine chains.
- LeanderK 10y agois this a limitation of C++ oder LLVM?
- wahern 10y agoIt's a limitation of C++. The reason is to avoid breaking interoperability with C and the hosts' existing calling conventions. They probably made the right decision. C++ is already heavy on dynamic allocation, so I don't really see it being a significant issue by itself. But from a code composability standpoint there's a huge gulf between stackful and non-stackful coroutines. People don't see it because it's actually a rare feature supported by only a few mainstream languages (Lua, Go, Modula). It's hard to appreciate something you've never really used. I like to think of stackful coroutines as similar to functions as first-class values. When you program in a language that supports functions as first-class values--especially with lexical binding--then function composition becomes much more natural. Similarly, when coroutines are stackful you'll use them more naturally, rather than relegate them to niche problems like async I/O. Put another way, when you don't need to decorate calls to coroutines, or when coroutines don't need to have a special type, coroutines become just like any other function. In particular, they can become blackboxes again, where you can use them as appropriate without the caller having to cooperate. If all functions were first-class values in C++, then non-stackful coroutines would be a real loss for the language because it would break symmetry. Because C++ doesn't have first-class functions, it's already normal to juggle different kinds of functions or function-like objects, so programming patterns are unlikely to change very much. So in that sense it's not that much of a loss, but effectively a net gain. I'd just like people to realize that not all coroutine implementations are the same. Many of the more elegant and seamless constructs just aren't possible with non-stackful coroutines, in the same way that some of the more elegant function composition patterns just aren't possible without functions as first-class values. And when writing languages from scratch it would be really nice for people to pay attention to these differences. Stackful coroutines are not easily added to a language design or implementation after the fact. It's why Python and JavaScript don't have them--because the existing implementations assume a fixed, contiguous C stack all over the code base, and refactoring those assumptions away is impractical, if not impossible without effectively a full rewrite.
- gumby 10y agoThis was exciting to me too but I couldn't tell how it is exposed in 4.0. All I could see from the notes and the discussion below was on the underlying implementation. Or perhaps I am blind? Will there be a library (stdc++) interface or...?