Overhead of -pthread compiler option?

125 views
Skip to first unread message

Mark Sibly

unread,
Sep 21, 2022, 8:23:36 PM9/21/22
to emscripten-discuss
Hi,

Does anyone have any idea what the overhead of using the -pthread compiler option is?

If I'm writing a simple single thread app, is it OK to just leave this on for all compilation units, but link the final exe without either -pthread or -sPTHREAD_POOL_SIZE? Would this give roughly the same output as compiling everything without -pthread?

Bye!
Mark


Thomas Lively

unread,
Sep 22, 2022, 12:08:46 AM9/22/22
to emscripte...@googlegroups.com
Hi Mark,

If you do that, the output will be roughly the same, but any atomic accesses you have would still use the atomic instructions. My understanding is that V8 at least uses the same codegen for atomic instructions no matter whether the memory is shared or not, so those atomic accesses would be slower than normal loads and stores. In principle V8 could optimize to use non-atomic loads and stores in this case, but I don't think it does. Compiling with threads enabled might also inhibit some optimizations around those atomic accesses that LLVM would have been able to do otherwise.

If you do end up trying this out, I would be very curious to hear what the overhead ends up being.

Best,

Thomas

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/40ce5767-d11d-4e7e-b44a-247137524b57n%40googlegroups.com.

Mark Sibly

unread,
Sep 25, 2022, 6:21:18 PM9/25/22
to emscripte...@googlegroups.com
After playing around with -pthread for a (very) short time, I don't think it's generally a good idea to use  -pthread only when compiling, as I'm guessing it causes the compiler to generate code that depends on symbols that can only be resolved by also linking with -pthread, so depending on what you #include you may or may not get a bunch of missing symbols at link time.

I think I'm OK with the overhead of -pthread at the source level (eg: adding locks to ref counts etc?) I guess what I'm really worried about is how much overhead a -pthread app will incur at runtime even if it doesn't create any threads. I vaguely remember hearing that web workers effectively 'forked' the entire process and am a bit worried that pthreads may do the same, even though it now seems like they shouldn't have to, given that the HEAP is now shared and CODE is read-only in wasm world. And the -sTHREAD_POOL_SIZE (I think) option implies to me emscripten is preallocating workers/threads which is a waste IMO if they are actually processes and my app never needs any of them! Maybe -sTHREAD_POOL_SIZE=0 could be used to indicate 'don't preallocate any workers' or something? Maybe it already does?

Gotta say though that the state of threads in Emscripten is way past when I last tried to use them a couple of years back! However, I do feel like the docs are lacking a bit. In particular, I feel like there should be a page for covering emscripten/threading.h that may be missing? Or can I just not find it? This file contains the hugely useful  MAIN_THREAD_EM_ASM*() and MAIN_THREAD_ASYNC_EM_ASM()  APIs (and I'm guessing is basically what gets imported when linking with -pthread), and it's only because these are briefly mentioned on the Wasm Workers API page I discovered they existed at all! However, for what I'm doing they were the last piece in the puzzle that let me add full thread support to the wasm version of my project, very cool!

Bye,
Mark

You received this message because you are subscribed to a topic in the Google Groups "emscripten-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/emscripten-discuss/kFbIbXAGVd0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/CAJZD_EWKYUgXAfOXFBYLFG384ciWN_DFjDmP%2B0MvtETrkWHrHA%40mail.gmail.com.

Jukka Jylänki

unread,
Sep 28, 2022, 6:41:35 AM9/28/22
to emscripte...@googlegroups.com
If you want to target browsers that do not support Wasm multithreading, then compiling any code with -pthread will cause issues, since those browsers won't recognize the atomics operations that get emitted.

Also notable is that the wasm linker will complain if linking in any set of object files that have a *mixed* use of the -pthread flag. So you'll have to be careful about compiling all object files consistently with that flag enabled if you go down that route. The linker will probably also complain if some objects were first compiled with -pthread, but if linking without -pthread (not 100% sure on that). So you will likely need to pass -pthread at link stage as well if you had that at compile stage.

Building with multithreading will cause performance issues if you are using --allow-memory-growth setting, though how much depends on how much Wasm<->JS interop your program has.

Passing -sTHREAD_POOL_SIZE=0 is a good idea, that will avoid prewarming background threads.

What the overall performance impact of the added atomics will be, depends on what your codebase eventually uses them on. The LLVM compiler will not spontaneously generate atomics in your code beyond what you instruct, except in a few special cases (e.g. one off startup time global data section init). Maybe this will become one of those "have to profile and see" things.

Finally if you are building with multithreading enabled, you will need to set up the COOP and COEP web server headers, even if your app will not spawn any threads.

Using MAIN_THREAD_(ASYNC_)EM_ASM is safe when building without -pthread, it will be a direct alias to regular EM_ASM. Good notes about missing documentation. Some of those APIs may indeed be best documented in the header files themselves. If you find glaring omissions, opening documentation page bugs is welcome.

Sam Clegg

unread,
Sep 28, 2022, 10:10:46 AM9/28/22
to emscripte...@googlegroups.com
On Sun, Sep 25, 2022 at 3:21 PM Mark Sibly <mark...@gmail.com> wrote:
After playing around with -pthread for a (very) short time, I don't think it's generally a good idea to use  -pthread only when compiling, as I'm guessing it causes the compiler to generate code that depends on symbols that can only be resolved by also linking with -pthread, so depending on what you #include you may or may not get a bunch of missing symbols at link time.

I think I'm OK with the overhead of -pthread at the source level (eg: adding locks to ref counts etc?) I guess what I'm really worried about is how much overhead a -pthread app will incur at runtime even if it doesn't create any threads. I vaguely remember hearing that web workers effectively 'forked' the entire process and am a bit worried that pthreads may do the same, even though it now seems like they shouldn't have to, given that the HEAP is now shared and CODE is read-only in wasm world. And the -sTHREAD_POOL_SIZE (I think) option implies to me emscripten is preallocating workers/threads which is a waste IMO if they are actually processes and my app never needs any of them! Maybe -sTHREAD_POOL_SIZE=0 could be used to indicate 'don't preallocate any workers' or something? Maybe it already does?


Indeed, the default for  THREAD_POOL_SIZE is zero which means no workers will be created until you call pthread_create.

Reply all
Reply to author
Forward
0 new messages