multi-memory
                                
                                
                                
                                    multi-memory copied to clipboard
                            
                            
                            
                        Use-case for multi-memory: Flutter Web Engine linking with wasm-compiled skia (C++) and ICU4X (Rust)
We are building a new mode for the Flutter Web Engine that compiles dart application code to WasmGC via the new dart2wasm compiler. As part of this effort, we are enabling direct wasm-to-wasm interop between the application wasm module and the skia wasm module. Our measurements have shown a serious improvement (~14x) in interop speed (vs JavaScript bindings) when wiring wasm imports and exports directly to each other. We have some other efforts we are working on to reduce code size which involve using a leaner version of skia which lacks some text layout functionality and supplementing that with ICU4X, which is a wasm-compiled Rust library.
However, without multi-memory support, linking directly on both of these modules and importing both of their memories is impossible.
Our measurements have shown a serious improvement (~14x) in interop speed (vs JavaScript bindings) when wiring wasm imports and exports directly to each other.
Sounds like a big difference! Just to be clear, are you comparing JS wrappers around exports to assigning one module's exports to another one's imports (and not a custom browser build, for example)?
Our measurements have shown a serious improvement (~14x) in interop speed (vs JavaScript bindings) when wiring wasm imports and exports directly to each other.
Sounds like a big difference! Just to be clear, are you comparing JS wrappers around exports to assigning one module's exports to another one's imports (and not a custom browser build, for example)?
Yes, this is using a normal browser and we're comparing JS wrappers around exports vs assigning imports and exports directly to each other.
Also, to be clear, this was a highly artificial benchmark where the work inside the actual function that is being called is really trivial. In real world scenarios, the cost of the function itself is likely to be more substantial. Nonetheless, it's clear that there are perf benefits to avoiding the JS path.
A few months ago @RossTate shared an interesting performance experiment, which showed that just making calls across module boundaries has a cost, but I am surprised that going through JS is this bad and curious to understand this better. Can you share some steps to reproduce? I assume this is in Chrome.
As for the multi-memory use, aside from multi-memory, you would need a tool that would put such multi-memory module together.
Binaryen used to have a module merging feature, that kind of worked like a naive linker. We're actively looking for reasons/use cases to bring it back and add support for multiple memories.
We have a similar use-case of linking with skia in Kotlin Compose UI framework. We also see interest from the Kotlin community in linking to external modules that use linear memory.
Kotlin/Wasm primarily uses WasmGC but also declares its own exported linear memory. It is used for constant data and temporary interop buffers. Sharing this memory with even a single C++/Rust external module currently implies the need for some form of allocation coordination.
Multi-memory proposal could help.