wasmi-labs / wasmi

WebAssembly (Wasm) interpreter.

Home Page:https://wasmi-labs.github.io/wasmi/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Optimize `Linker` setup

Robbepop opened this issue · comments

It was found that in the contracts-pallet the wasmi::Linker setup of all the 52 host functions for each call takes up to 30% of the total execution time in test cases where there are only cross-contract calls.

Note: This is to be expected since the contracts-pallet is not using Wasmi the way the Wasm spec or Wasmi itself are expected to be used where both Engine and Linker are long lived entities, whereas Instance and Store are rather short-lived entities.

However, due to memory consumption limitations we cannot really change anything about the way the contracts-pallet inherently uses Wasmi. Therefore we need to optimize wasmi::Linker when populating it with host functions.

An alternative optimization is to only populate the wasmi::Linker with those host function calls that are actually used. However, this requires to store some persistent information per uploaded smart contract.

Optimization Possibilities

  1. Make wasmi::Linker::define and subsets faster: Not sure what is the bottle-neck, yet but if we find one we should work on that. Note that use of atomics is not an issue here since the contracts-pallet uses Wasmi within Wasm itself which has no notion of atomics, thus atomics are getting compiled down to non-atomic primitives.

  2. Introduce new abstractions that allow to pre-populate a wasmi::Linker before actually creating a Linker thus speeding up the population process. This could mean to introduce a HostApi type which can be populated once and re-used to create new wasmi::Linker instances. The question is: can we do that? And how much faster can we get?

  3. Add new wasmi::Module::new_with_linker API that takes a &mut wasmi::Linker and feeds it whenever the parsing notices an import to tell the Linker that the import is going to be required. This way we could create an empty wasmi::Linker and only feed it with what the parsed wasmi::Module actually needs. The big downside to this approach is weights calculation since then the pallet-contracts needs to charge for every used imported host function per call since that cost is no longer fixed.