tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

Support for multi threading in WASM?

Open ibudisteanu opened this issue 3 years ago • 24 comments

Does Tinygo support multi threading in web assembly? If not, is there any date when tinygo would add support for multi threading ? WebAssembly is useful for CPU intensive, but it such a pity that golang doesn't support multi threading in wasm...

ibudisteanu avatar Feb 11 '22 18:02 ibudisteanu

The current tinygo implementation supports cooperative goroutines using asyncify on wasm. Does that solve your problem?

dgryski avatar Feb 14 '22 19:02 dgryski

Wait what ? Could you give us some links to read more about it? Does it mean, that multiple goroutines run multi threaded in tinygo wasm ?

ibudisteanu avatar Feb 14 '22 19:02 ibudisteanu

Yes. The tinygo 0.22 release includes asyncify support which solved all the memory corruption issues with the coroutine scheduler.

dgryski avatar Feb 14 '22 19:02 dgryski

Thanks for your reply! I really appreciate it! From my understanding multi threading in wasm is done running multiple and separate WebWorkers and exchange data either using SharedArrayBuffer or using processMessage() . From my understanding asyncify doesn't make the goroutine run multi threaded. Am I wrong ?

ibudisteanu avatar Feb 15 '22 11:02 ibudisteanu

Correct, there is still only a single wasm "core".

dgryski avatar Feb 15 '22 18:02 dgryski

Then, there is no multi threading support right now in tinygo in wasm. Any plans of adding support for multi threading wasm ? Take a look here https://github.com/w3reality/wasm-mt

Our open source library does a lot of heavy computations (zero knowledge proofs) and it takes 20 seconds single threaded. Using multi threading, we can reduce it down to 3-4 seconds?

ibudisteanu avatar Feb 15 '22 19:02 ibudisteanu

Would "multicore support" be a better title?

dkegel-fastly avatar Feb 19 '22 15:02 dkegel-fastly

It would be amazing of having multicore support wasm bundles.

ibudisteanu avatar Feb 19 '22 16:02 ibudisteanu

I think the easiest way to integrate it is via SharedArrayBuffer which was re-enabled in Google Chrome v67

ibudisteanu avatar Feb 19 '22 16:02 ibudisteanu

The threading proposal for Wasm is not finished, and wasm-mt is a library while TinyGo is a compiler, so really you cannot compare them. Personally I don't think there is anything to do here for the time being.

fgsch avatar Feb 19 '22 18:02 fgsch

The threading proposal for Wasm is not finished

In the meantime, the threading proposal for Wasm is finished.

It would be very interesting (really very interesting) to use tinygo to write multithreaded wasm programs.

Please consider this.

https://webassembly.org/roadmap/ https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md https://web.dev/webassembly-threads/

edwinm avatar Jun 09 '23 22:06 edwinm

Unfortunately, the "threading proposal" doesn't actually provide a way to start a thread. It's only about shared memory and atomics. No idea who thought that would be a good name.

So that proposal is useless in itself, it only becomes useful together with an embedder specified way of starting threads (Web Workers for example). Last time I checked, WASI didn't have a way of starting threads making it pretty useless there.

Also, wasm threading depends on general support for parallelism is TinyGo, which doesn't exist at the moment: https://github.com/tinygo-org/tinygo/issues/2446

aykevl avatar Jun 11 '23 13:06 aykevl

Unfortunately, the "threading proposal" doesn't actually provide a way to start a thread. It's only about shared memory and atomics.

The last article I mentioned addresses a list of problems (with solutions) and one of them is the inability to start a thread.

"In C, particularly on Unix-like systems, the common way to use threads is via POSIX Threads provided by the pthread library. Emscripten provides an API-compatible implementation of the pthread library built atop Web Workers, shared memory and atomics, so that the same code can work on the web without changes."

If it's available in C, it should be available in TinyGo, I suppose.

Also, wasm threading depends on general support for parallelism is TinyGo, which doesn't exist at the moment

Oh, that's too bad, I didn't know. I'll stick with C, then.

I don't want to sound harsh. I think TinyGo is an interesting project, both for wasm and for microcontrollers. I'm looking forward to the moment parallelism is added.

edwinm avatar Jun 11 '23 21:06 edwinm

This looks apropos: https://bytecodealliance.org/articles/wasi-threads

dkegel-fastly avatar Jun 12 '23 00:06 dkegel-fastly

Hi folks, any plans to address this now that the WASM threads proposal has entered Stage 4 of standardization and is supported in all modern browsers? https://github.com/webassembly/threads

There's a similar issue in the main Go repo that was stalled pending standardization of the proposal, it's far enough along that there's little chance of spec change at this point.

This feature is blocking Go's utility in the WASM world, since one of the main benefits of Go (the versatility of goroutines) is kneecapped without proper procs. https://github.com/golang/go/issues/28631

esimkowitz avatar Oct 15 '24 22:10 esimkowitz

The standard still doesn't specify how to create a thread, so it seems incomplete...? https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md

dkegel-fastly avatar Oct 16 '24 00:10 dkegel-fastly

Maybe a bit naive but the spec sounds to me like an abstraction of Web Workers and there's a pthread implementation that interfaces with this to create threads so why can't TinyGo utilize this?

esimkowitz avatar Oct 16 '24 05:10 esimkowitz

TinyGo does not support multithreading yet, on any platform. It's not as simple as just running every goroutine in a separate thread. For an overview, see: https://github.com/tinygo-org/tinygo/issues/2446. But in short: things like the sync package, channels, and the GC also need to be able to live in a multithreaded world (for example, the GC can't assume that if it runs, no other threads are running).

The standard still doesn't specify how to create a thread, so it seems incomplete...? https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md

Indeed. On the web it's typical to use Web Workers. For WASI there's the wasi-threads proposal that has been deprecated already. The consensus seems to be that both should be replaced with shared-everything threads, which will be built into WebAssembly instead of being specific to every host API.

aykevl avatar Oct 16 '24 08:10 aykevl

Ah, didn't realize it wasn't supported by TinyGo period, that would certainly be a blocker. I was imagining it would be more like a thread pool like in other runtime langs, but yeah if it's not supported at all that's a different story. Will pursue in the main Go repo...

esimkowitz avatar Oct 16 '24 22:10 esimkowitz

It's possible that even big Go will have trouble here. Often tinygo leads on wasm support, and big go follows.

dkegel-fastly avatar Oct 17 '24 00:10 dkegel-fastly

It's possible that even big Go will have trouble here.

As far as I'm aware, they don't support threading either.

aykevl avatar Oct 17 '24 08:10 aykevl

As far as I'm aware, they don't support threading either.

Big Go definitely supports concurrency via procs, which queue on threads...

esimkowitz avatar Oct 17 '24 16:10 esimkowitz

As far as I'm aware, they don't support threading either.

Big Go definitely supports concurrency via procs, which queue on threads...

According to this issue, they don't support multithreading in WebAssembly: https://github.com/golang/go/issues/28631

aykevl avatar Oct 17 '24 17:10 aykevl

Right, that's what I want to push them on 😉

AFAICT all the prerequisite features should be there now so it's just a matter of implementation. Not discounting that that is a tall order, but it feels weird that no effort is even being made...

esimkowitz avatar Oct 17 '24 17:10 esimkowitz

Tinygo seems to already use asyncify for wasip2, is it possible to use this to make async calls to JS code outside the Go program?

paralin avatar Mar 18 '25 19:03 paralin

Multithreading is still poorly supported across systems. We could add support for it in browsers, using Web Workers. But I believe that requires the website to be cross-origin isolated (which is not always easy to do). There is some (already deprecated) support in wasmtime, but since it's deprecated I don't want to spend much time on it.

Eventually we should have shared-everything threads. I would prefer to focus efforts on this, once the spec finally stabilizes.

(Also, update: TinyGo now does support threading, so that is no longer a blocker - we just don't support it for WebAssembly yet).

aykevl avatar Sep 30 '25 08:09 aykevl

Go and its insistence on specs vs. proposals 🙃

esimkowitz avatar Sep 30 '25 22:09 esimkowitz