GorNishanov / coroutines-ts

20 stars 2 forks source link

Suggest explicit placement for coroutine frames #26

Open imoldfella opened 6 years ago

imoldfella commented 6 years ago

I would like to suggest adding a way to directly place coroutine frames in memory, analogous to placement new. I wrote a short benchmark that shows when reusing a large number of coroutines old switch style coroutines are significantly faster due to the control over placement. Even using an unrealistically fast allocator with experimental::generator there was a 2x difference.

edit: I wrote a placement allocator that got the difference down to 30-40% depending on whether indirection is needed or can be optimized away. Its weird and awkward and has all the normal problems of a non-default allocator. Hopefully the TS can add a better method that doesn't need a special allocator.

https://gist.github.com/imoldfella/ea264e146df67884056da0af1e61964f

imoldfella commented 6 years ago

Here's a thought:

  1. compile time operator co_size(expr) where expr evaluates to a coroutine and returns the size in bytes.
  2. co_var<size_t,typename T> - provides a value holding a coroutine frame of size_t bytes, and has promise T.
  3. co_move(expr) destroys the old frame and returns a co_var<co_size(expr),...>

One problem I see with this is that a coroutine can't always be moved; e.g. it may have co_yield'ed a pointer to something in its coroutine frame. Ideally co_move could give a static error if it can't prove that the coroutine is moveable. Potentially we could use co_emplace(co_var<>&,expr) to build a coroutine frame in a specific place. This could allow a coroutine with immovable arguments to be built in place.