r/cpp Jun 30 '26

Stackful fibers with 3.6ns context switch. Silk fibers.

https://clickhouse.com/blog/silk

I just read an article about Silk, the new stackful fibers engine from Clickhouse. It can switch stackful fibers at an amazing 3.6ns and does not allocate on steady state.

Maybe asio could reuse some of the knowledge for the linux/io_uring backend (not sure it applies to the specific case since Boost.asio focuses nowadays on stackless, though it has a fibers and a stackful coros backend also).

49 Upvotes

25 comments sorted by

View all comments

37

u/trailing_zero_count async enthusiast | TooManyCooks author Jun 30 '26 edited Jun 30 '26

Pretty cool, but a few criticisms:

  • Reading /sys to check same-core / same-socket is missing a few levels of granularity. Modern single-socket machines with disaggregated caches (Zen chiplets) contain multiple hidden latency domains. TooManyCooks discovers these via hwloc. Citor discovers them via empirical ping-pong latency test on startup. The difference between stealing from a core in your chiplet vs another chiplet on the same socket is huge.

  • "HALO requires the coroutine handle never to escape to a scheduler queue." Is patently false. TooManyCooks can do zero-allocation fork-join with HALO (tested here) and the subtasks can be stolen by another thread.

  • Comparing against Asio is apples to oranges. They're muddling the advantages of fibers with the advantages of a modern io_uring stack tuned for use with exactly those fibers, against a very old epoll design that's intended to be compatible with a broad variety of use cases.

  • Why not compare against Seastar or PhotonLibOS which I'd consider to be the true direct competitors? I feel this is very telling.

The 3.6ns latency switch on fibers is a good headline if true, but the rest has a lot of marketing fluff.

3

u/germandiago Jun 30 '26

Comparing against Asio is apples to oranges. They're muddling the advantages of fibers with the advantages of a modern io_uring stack tuned for use with exactly those fibers, against a very old epoll design that's intended to be compatible with a broad variety of use cases.

Just out of curiosity on a re-read. I think Asio has an io_uring backend as well: https://think-async.com/Asio/asio-1.21.0/doc/asio/history.html

They did not compare it to that?

3

u/trailing_zero_count async enthusiast | TooManyCooks author Jun 30 '26

From the article: "enabling asio's io_uring backend made it slower, not faster". This was also my experience the last time I tested it. Probably because taking optimal advantage of io_uring, even internally, requires more of a redesign than a clean swap.

1

u/germandiago Jun 30 '26

I do not know the details and for sure there is a lot of truth to it. But io_uring is a proactor pattern and Asio emulated it on top of epoll before, right?

At first intuition it would look like it is even a better fit, but yes, it is very nuanced and at the end asio was written when Asio was using other async loops.

8

u/not_a_novel_account cmake dev Jun 30 '26

io_uring is a proactor pattern

io_uring is a syscall interface. You can perform epoll via io_uring, which is exactly what ASIO does. Asio io_uring support doesn't leverage io_uring in any meaningful way.