tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.51k stars 914 forks source link

Support for multi threading in WASM? #2630

Open ibudisteanu opened 2 years ago

ibudisteanu commented 2 years ago

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...

dgryski commented 2 years ago

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

ibudisteanu commented 2 years ago

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 ?

dgryski commented 2 years ago

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

ibudisteanu commented 2 years ago

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 ?

dgryski commented 2 years ago

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

ibudisteanu commented 2 years ago

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?

dkegel-fastly commented 2 years ago

Would "multicore support" be a better title?

ibudisteanu commented 2 years ago

It would be amazing of having multicore support wasm bundles.

ibudisteanu commented 2 years ago

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

fgsch commented 2 years ago

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.

edwinm commented 1 year ago

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/

aykevl commented 1 year ago

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

edwinm commented 1 year ago

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.

dkegel-fastly commented 1 year ago

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

esimkowitz commented 1 month ago

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

dkegel-fastly commented 1 month ago

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

esimkowitz commented 1 month ago

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?

aykevl commented 1 month ago

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.

esimkowitz commented 1 month ago

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...

dkegel-fastly commented 1 month ago

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

aykevl commented 1 month ago

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

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

esimkowitz commented 1 month ago

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

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

aykevl commented 1 month ago

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

esimkowitz commented 1 month ago

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...