silkworm
silkworm copied to clipboard
Investigate overhead of asynchronous state access
For better performance in things like eth_call in SilkRPC it makes sense to have asynchronous API in silkworm::State (SilkRPC uses Boost.Asio coroutines and the state in question is in a remote DB). But async APIs are contagious and making silkworm::State use coroutines means that we'll have to use them in EVMC, evmone, and Silkworm execution itself. That's the route taken by Akula.
The goal of this experiment is to assess performance overhead of (probably Boost.Asio) coroutines on the staged sync execution (where we don't really need async API). So the task is to fork EVMC, evmone, and Silkworm, switch them to async API with coroutines (C++20 is a prerequisite), and check what's the slowdown (if any) of the execution stage.
P.S. There's a plan for coroutine library support, executors, and networking in C++23. Let's hope it materializes, but right now we can play with Boost.Asio.
@yperbasis would it be possible to implement SilkRPC in a separate process (accessing the same libmdbx database) to avoid the async API contagion?
@yperbasis would it be possible to implement SilkRPC in a separate process (accessing the same libmdbx database) to avoid the async API contagion?
Actually is what rpcdaemon does for erigon. There are caveats though:
- access to same db can occurr only if Silkworm and SilkRpc are on the same host
- there can be multiple Silkrpc instances
@AndreaLanfranchi , does Erigon's rpcdaemon use asynchronous i/o? Does it help with performance of the rpc endpoint?
I'm not opposed to any of these. Upgrading evmone to C++20 is definitely doable. The executors and networking will not actually be part of C++23 so don't count on these.
I have very little understanding of async programming. Can you point me the code in evmodin which uses async so I can see the difference in the EVM design?
We can ignore EVMC.
@chfast It looks to me like https://github.com/vorot93/evmodin/pull/2 is relevant here. @vorot93 what was the reason behind this change? Was async too slow?
@AndreaLanfranchi , does Erigon's rpcdaemon use asynchronous i/o? Does it help with performance of the rpc endpoint?
@greg7mdp sorry for being so late in the response (I totally skimmed over it). Erigon's rpcdaemon has two ways to access db ... both syncronous
- shared memory : rpcdaemon process opens the same MDBX environment as Erigon's in shared mode (so they share the same memory mapping). Better performance
- remote : via tcp socket RPC calls to Erigon (usually used when erigon and rpcdaemon do not live in the same host). Slower
- shared memory : rpcdaemon process opens the same MDBX environment as Erigon's in shared mode (so they share the same memory mapping). Better performance
- remote : via tcp socket RPC calls to Erigon (usually used when erigon and rpcdaemon do not live in the same host). Slower
Thanks for the answer @AndreaLanfranchi. I'm still having a hard time understanding the original issue, because it seems that silkrpc is also run as a separate process, in which case I don't see why using async i/o in this (silkrpc) process would require the same change in silkworm?