-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document best practices around invoking a wasi module multiple times #985
Comments
I'll give a quick answer as we've had some chats about this on #wazero-dev gophers slack. The TL;DR; is that In any case, always close modules when done with them, unless you are only initing one per runtime and the runtime closes it. So, when any module is no longer needed, either due to its work being complete via init, or you no longer need its exports, close it. This advice applies to all guests, not just WASI. If you didn't ask about wasi, and were asking about things that could be re-used (exported functions), I would suggest pooling as is done here. https://github.com/http-wasm/http-wasm-host-go/blob/main/handler/middleware.go#L151 -- more notes on wasi We've tried it and the compilers don't expect that to run again. Many times, they will do things like "unreachable", and the behaviors of trying to execute "_start" again aren't something we can affect (as it is in how wasi-libc is used by compilers often enough. help wanted to raise a PR in a place that makes sense weaving in this advice. |
Thanks for the quick response @codefromthecrypt
My question was mostly about wasi, so thanks for the clarifications.
I'll give this a try once I figure out where it belongs. |
I have create a golang wasm cgi server based on how to improve reuse wasi module performance? Thank you for any reply!
package main
import "log"
func init() {
log.Println("init")
}
func main() {
log.Println("main")
}
package main
import (
"context"
_ "embed"
"os"
"os/exec"
"sync"
"testing"
"github.com/shynome/err0/try"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)
func TestMain(m *testing.M) {
cmd := exec.Command("go", "build", "-o", "z.wasm", ".")
env := os.Environ()
env = append(env, "GOOS=wasip1", "GOARCH=wasm")
cmd.Env = append(cmd.Env, env...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
try.To(cmd.Run())
wasm := try.To1(os.ReadFile("z.wasm"))
ctx := context.Background()
rtc := wazero.NewRuntimeConfigCompiler()
rt = wazero.NewRuntimeWithConfig(ctx, rtc)
wasi_snapshot_preview1.MustInstantiate(ctx, rt)
cm = try.To1(rt.CompileModule(ctx, wasm))
m.Run()
}
var (
rt wazero.Runtime
cm wazero.CompiledModule
)
func BenchmarkWASI(b *testing.B) {
ctx := context.Background()
mc := wazero.NewModuleConfig().
WithSysNanotime().
// WithStderr(os.Stderr).
// WithStdin(os.Stdin).
// WithStdout(os.Stdout).
WithName("")
var wg sync.WaitGroup
wg.Add(b.N)
for range b.N {
go func() {
defer wg.Done()
mc := mc.WithName("")
mod := try.To1(rt.InstantiateModule(ctx, cm, mc))
mod.Close(ctx)
}()
}
wg.Wait()
} I fix |
In your benchmark, you're not calling Back to your server, if you don't compile the module on your hot path (and you probably don't, if you get 100 qps), there's not much more to do. |
Thanks for your tips. I have update benchmark, the new performance is 137 qps, it is too slow. how do improve reuse wasi module performance?
sorry I ignore this Thanks for your reply again! golang wasip1 300 qps by wasmer wcgi, so maybe the problem is golang wasm is too big to exceute quickly |
Yes, and I don't think Go likes to have You should (maybe) consider TinyGo for the guest, and export functions, so you only instantiate once, and then call functions from an already instantiated module. |
Is your feature request related to a problem? Please describe.
Not a problem per se, just questions around writing production-grade code with Wazero.
Context:
I have a simple Rust program that looks like this:
It's been compiled with
cargo wasi build --release
and produced a binary.Validating it works as expected with
wasmtime
:I would like to provide a Go library that embeds this wasm binary.
Here's what it currently looks like, with non critical sections elided:
which would be used like this:
Describe the solution you'd like
It would be greatly beneficial to have documented best practices around how to optimize running a wasi module multiple times.
Questions that could benefit from being documented
What are the best practices around invoking a wasi module multiple times?
What are the performance implications of using wasi vs a standard wasm module?
Is it preferable to close the module each time:
or invoking it with a different name without closing it:
Additional context
Wazero has been extremely fun to build prototypes with, and I'm curious about how to start working on production-grade code. A canonical production ready example would be a great starting point for many new projects.
The text was updated successfully, but these errors were encountered: