Skip to content

Add an Emscripten/wasm implementation of primitives #822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

kripken
Copy link
Contributor

@kripken kripken commented Nov 8, 2023

This PR adds a prim implementation for the Emscripten wasm toolchain. There is already a WASI wasm prim in mimalloc, which this is separate from. WASI tends to be used on the server, and Emscripten on the browser, and there are API differences that led to a different design here. Another difference is that Emscripten has stable support for multithreading, and so that part is fully implemented here (it was the main reason for the port, actually - to get a malloc that scales well with multiple cores).

The overall idea in this implementation is to build on top of emmalloc as the "system allocator". emmalloc is a minimal allocator in Emscripten, so it can be used to provide a VirtualAlloc-like API. This avoids using sbrk directly, which could lead to problems with returning memory to the OS (fragmentation and leaks).

There is a PR up on the Emscripten repo with all the integration into our toolchain so that people can test it out there. Also some charts with numbers, which look great!

Thank you for the mimalloc project ❤️ it was very easy to build support for, and as the numbers there show now we have an option for a malloc implementation that looks like it scales really well, in fact just as good as native builds.

@kripken
Copy link
Contributor Author

kripken commented Nov 30, 2023

@microsoft-github-policy-service agree [company="google"]

@kripken
Copy link
Contributor Author

kripken commented Nov 30, 2023

@microsoft-github-policy-service agree company="google"

@daanx daanx changed the base branch from master to dev March 2, 2024 22:51
@daanx daanx changed the base branch from dev to master March 2, 2024 22:51
@daanx
Copy link
Collaborator

daanx commented Mar 2, 2024

Ah this is awesome -- apologies for the later reaction! I love emscripten -- the Koka compiler uses it as well and it would be good to have a more native implementation.

@daanx
Copy link
Collaborator

daanx commented Mar 2, 2024

I merged your PR manually into the dev branch (as you based on master) -- hope that is ok with you. I added credits of course.
This looks great -- and good to hear the performance seems good. The arena reserve should be 256MiB at a time so I think the alignment on 4MiB is not a real problem. Within the large arena's mimalloc will efficiently (re)use the memory (so even using sbrk will not be a problem as mimalloc will manage large chunks at a time.

@kripken
Copy link
Contributor Author

kripken commented Mar 4, 2024

Great, thanks for merging! And sorry I didn't know the PR should target dev.

I'll close this PR then.

Btw, recently I saw a 5x speedup using mimalloc over dlmalloc and we have other positive reports coming in from other Emscripten users. Thanks again for mimalloc!

@kripken kripken closed this Mar 4, 2024
@kripken kripken deleted the emscripten.upstream branch March 4, 2024 20:47
// we may want to improve emmalloc to support such alignment. See also
// https://github.com/emscripten-core/emscripten/issues/20645
#define MIN_EMMALLOC_ALIGN 8
#define MAX_EMMALLOC_ALIGN (1024*1024)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming back to this: is it possible to make the MAX_EMMALLOC_ALIGN equal to MI_SEGMENT_ALIGN (=4MiB) ? As it is now, it will never use the right alignment, and mimalloc will retry with size + 4MiB and align within that area itself. (see os.c:mi_os_prim_alloc_aligned)

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I see we fixed this in emmalloc in emscripten-core/emscripten#20704 😄

So, yes, the MAX_EMMALLOC_ALIGN can be removed.

Copy link
Contributor Author

@kripken kripken May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened emscripten-core/emscripten#21905 on Emscripten to verify that all tests pass with that, and after that will open a PR here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kripken
Copy link
Contributor Author

kripken commented Jan 31, 2025

fyi, we posted about the benefits of mimalloc in Emscripten here:

https://web.dev/articles/scaling-multithreaded-webassembly-applications?hl=en#mimalloc

Thanks again for the great allocator!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants