Stream: wasmtime

Topic: Multiple stores for concurrent execution


view this post on Zulip Giacomo C. (Sep 18 2024 at 08:49):

I would like to run multiple concurrent functions from a bundle of linked modules. No memory is used from these modules, only non-mutable access to store data. In that case, can I link/instantiate modules once and bind them into a Linker and finally clone the linker and use it with another store that references the same data with an Arc?

view this post on Zulip Dave Bakker (badeend) (Sep 18 2024 at 08:54):

Can you use Arc<YourSharedData> as the T of Linker?

view this post on Zulip Giacomo C. (Sep 18 2024 at 10:03):

Yup, that's the plan.

view this post on Zulip Giacomo C. (Sep 18 2024 at 10:05):

In that case, can I create a new Store each time I want to call a Func or do I need to keep it consistent with previous module instantiation and registration calls?

view this post on Zulip Giacomo C. (Sep 18 2024 at 10:06):

(considering I'm not using Globals or Memory)

view this post on Zulip Dave Bakker (badeend) (Sep 18 2024 at 10:11):

If the Module is truly stateless, you could probably get away with keeping only a fixed set (e.g. one per thread) of stores & module-instances. And reuse them to call the module exports on

view this post on Zulip Giacomo C. (Sep 18 2024 at 10:13):

So I need to create module instances for each thread. Is there a cheaper way? If only Store were clonable...

view this post on Zulip Dave Bakker (badeend) (Sep 18 2024 at 10:13):

Also maybe of interest is: InstancePre

view this post on Zulip Giacomo C. (Sep 18 2024 at 10:14):

aha, cool!

view this post on Zulip Giacomo C. (Sep 18 2024 at 10:14):

So I can pre-instantiate modules once and then clone it to each thread.

view this post on Zulip Giacomo C. (Sep 18 2024 at 10:15):

much better, thanks :-)

view this post on Zulip Alex Crichton (Sep 18 2024 at 15:03):

I can confirm you'll want an instance-per-thread model at least here because you can only call functions on instances and an instance cannot itself be used concurrently on more than one thread at a time. Creation of a Store should be cheap so if you find that being a hot spot let us know so we can optimize it

view this post on Zulip Giacomo C. (Sep 19 2024 at 08:44):

I was wondering: if I receive a func as return type from a call, is there a way to call it on a different store, given that such stores have no memory/globals and instance were imported the same way in all stores?

view this post on Zulip Lann Martin (Sep 19 2024 at 14:14):

Could you clarify what you mean by "receive a func as return type"? Are you referring to the function references proposal?

view this post on Zulip Giacomo C. (Sep 19 2024 at 14:55):

Yup. I noticed "Val" can contain a variant Val::Func(Option<Func>).

view this post on Zulip fitzgen (he/him) (Sep 19 2024 at 14:59):

No, a Func is associated with a particular Store. Especially a Func that represents an underlying Wasm function.

A Store is the lifetime/context/data for a set of Wasm instances, so if the Store goes away or the wrong Store is paired with some operation, we can't really do anything

view this post on Zulip Giacomo C. (Sep 19 2024 at 15:06):

Ok, I see. Is there a way to resolve a Func pointer back to the function name, if it's exported? The "one instance-set/store per thread" model is getting very strict if what starts in one thread must always live in the same thread for the whole duration of the pool.

view this post on Zulip fitzgen (he/him) (Sep 19 2024 at 15:07):

you can have multiple stores on a single thread, and you can also send a store to a different thread, it just isn't Sync

view this post on Zulip fitzgen (he/him) (Sep 19 2024 at 15:09):

regarding function names: I don't think we expose anything like that. it gets a little tricky where a function can be defined in one module and given a name there, and then imported in another module and given a different name there, so I'm not sure which name we would expose as the canonical one in this case. but we could probably create something to expose the name from the custom names section, if any

view this post on Zulip Lann Martin (Sep 19 2024 at 15:13):

Could you say more about what you're trying to do? It could be reasonable - for example - for a module to return the name of a func it "knows" it exports and the host could call that dynamically on a different instance of that module

view this post on Zulip Giacomo C. (Sep 19 2024 at 15:16):

My current situation is this: I would like to build modules that can manage higher order functions (as in: return function ptrs, receive function ptrs as parameters) and I would like to possibly run such higher order functions in a concurrent way, possibly making use of multiple threads.

view this post on Zulip Giacomo C. (Sep 19 2024 at 15:21):

Initially, I thought that this would only resolve in having one Store for each thread, but since function pointers only make sense in the same Store they came from, I think I've hit a wall.

view this post on Zulip fitzgen (he/him) (Sep 19 2024 at 15:21):

sharing and calling function references from the same instance, concurrently across threads is fundamentally impossible in Wasm without the shared-everything proposal, which is still very much in flux at the standards level, and not implemented in wasmtime yet

A draft proposal for spawning threads in WebAssembly - WebAssembly/shared-everything-threads

view this post on Zulip fitzgen (he/him) (Sep 19 2024 at 15:23):

the proposal is currently in phase 1 out of 5: https://github.com/WebAssembly/proposals?tab=readme-ov-file#phase-1---feature-proposal-cg

Tracking WebAssembly proposals. Contribute to WebAssembly/proposals development by creating an account on GitHub.

view this post on Zulip Giacomo C. (Sep 19 2024 at 15:27):

I see. Thanks for your support, it really helped to avoid going in the wrong direction :-)

view this post on Zulip fitzgen (he/him) (Sep 19 2024 at 15:28):

good luck!

view this post on Zulip Giacomo C. (Sep 19 2024 at 15:29):

hehe


Last updated: Dec 23 2024 at 14:03 UTC