deislabs / wagi

Write HTTP handlers in WebAssembly with a minimal amount of work

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

prepare_wasm_instance consuming too much CPU

denverdino opened this issue · comments

commented

In src/wasm_runner.rs the prepare_wasm_instance() will create and instantiated linker for every request, it will consume about 80% CPU time during stress testing.

pub fn prepare_wasm_instance(
    ctx: WasiCtx,
    wasm_module: &WasmModuleSource,
    link_options: WasmLinkOptions,
) -> Result<(Store<WasiCtx>, Instance), Error> {
    debug!("Cloning module object");
    let (module, engine) = wasm_module.get_compiled_module()?;
    let mut store = new_store(ctx, &engine)?;

    debug!("Configuring linker");
    let mut linker = Linker::new(&engine);
    wasmtime_wasi::add_to_linker(&mut linker, |cx| cx)?;
    link_options.apply_to(&mut linker)?;

    debug!("instantiating module in linker");
    let instance = linker.instantiate(&mut store, &module)?;
    Ok((store, instance))
}

The profiling result is enclosed

flamegraph-before

I create a quick prototype to cache the linker for each compiled wasm module, the cold start time is reduced a lot. The profiling result after optimization is enclosed. it will only consume about 18% CPU time.

flamegraph-after

Just want to know your suggestion for that. Thanks

Thanks for this. Might be worth checking out how the SpIn environment (https://github.com/fermyon/spin/tree/main/crates/http/src) sets up WAGI, because Spin also does extensive pre-warming that I think might go even further than this. We need to figure out whether to use your fixes or backport Spin's - I am not sure of the comparative performance implications.