silkworm icon indicating copy to clipboard operation
silkworm copied to clipboard

Investigate overhead of asynchronous state access

Open yperbasis opened this issue 4 years ago • 7 comments

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 avatar Sep 07 '21 09:09 yperbasis

@yperbasis would it be possible to implement SilkRPC in a separate process (accessing the same libmdbx database) to avoid the async API contagion?

greg7mdp avatar Oct 04 '21 14:10 greg7mdp

@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 avatar Oct 04 '21 14:10 AndreaLanfranchi

@AndreaLanfranchi , does Erigon's rpcdaemon use asynchronous i/o? Does it help with performance of the rpc endpoint?

greg7mdp avatar Oct 04 '21 19:10 greg7mdp

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 avatar Nov 16 '21 10:11 chfast

@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?

yperbasis avatar Nov 16 '21 11:11 yperbasis

@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

AndreaLanfranchi avatar Dec 30 '21 18:12 AndreaLanfranchi

  • 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?

greg7mdp avatar Dec 30 '21 19:12 greg7mdp