Skip to content
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

Increase WASM_BINDGEN_THREADS_MAX_MEMORY to 65536 #2498

Closed
mattgibb opened this issue Mar 17, 2021 · 5 comments
Closed

Increase WASM_BINDGEN_THREADS_MAX_MEMORY to 65536 #2498

mattgibb opened this issue Mar 17, 2021 · 5 comments
Labels

Comments

@mattgibb
Copy link

mattgibb commented Mar 17, 2021

Summary

I'd love to be able to use 4gb of memory, but am not managing to get it to work, either in the wasm binary or in the generated bindings.

Feels like I'm nearly there, but haven't quite managed to figure it out and a bit stumped. Sorry to bother and thanks for building all this amazing stuff, any pointers would be super appreciated!

Additional Details

I was processing some beefy medical images in the browser and running into memory issues. I've managed to get threads working with the parallel-raytracing example, which is absolutely amazing thanks! Using the config and flags from parallel-raytracing, I can see that rustc generates a wasm binary that is expecting some shared memory with 1GB max capacity:

wasm-objdump --details --section=import target/wasm32-unknown-unknown/release/a_fancy_library.wasm | grep memory

I found the cheeky WASM_BINDGEN_THREADS_MAX_MEMORY env var in the cli-support crate here, but it wouldn't seem to work when I exported WASM_BINDGEN_THREADS_MAX_MEMORY=65536, either in the bindings or any wasm transformation.

On the wasm generation side of things, I found the "-z stack-size=1048576" in wasm32_base.rs, but this seems to be the initial 1M (or 16 64kb pages) allocation, rather than the maximum...? Even though the generated binary has an initial 17 pages...

Next actions might be:

  • somehow find the magic compiler/linker flag that makes everything work
  • use walrus to edit the generated wasm binary after the fact?
  • write some hacky bash/xxd script to change the number in the binary, and sed -i '' 's/maximum:16384/maximum:65536/' pkg/a_fancy_library.js in the bindings... 👎

I have a feeling there is some hard reason why the default isn't at least 2GB and up to 4GB, perhaps performance, or portability across browsers? If not, I'd be delighted to work on this feature and submit a PR if someone could point me in the right direction!

@ghost
Copy link

ghost commented Mar 17, 2021

Not all Wasm VMs were always capable of allocating massive amounts of memory such as 2GB+, and they are allowed (by the spec) to trap upon attempting to grow memory due to OOM at any given attempt.
Here's V8 blog on it: https://v8.dev/blog/4gb-wasm-memory

So, not all browsers, devices, or browser versions will allow addressing 4GB, but, beyond that, it still is very possible to address large amounts of memory, so rustc/wasm-bindgen should allow emitting binaries that can take advantage of this.

@alexcrichton
Copy link
Contributor

If this env var doesn't work that's likely just a bug in wasm-bindgen's thread transformation pass right now. Shouldn't be too hard to fix hopefully!

@mattgibb
Copy link
Author

Awesome thanks peeps! In that case I'll have a crack at fixing it

@mattgibb
Copy link
Author

mattgibb commented Mar 17, 2021

Sweet, @alexcrichton I found this little gem that you wrote 2 years ago! I thus discover that link-arg is a thing, and the wasm now generates with 4GB:

$ export RUSTFLAGS='-C target-feature=+atomics,+bulk-memory -C link-arg=--max-memory=4294967296'
$ cargo build --lib --release --target wasm32-unknown-unknown -Z build-std=std,panic_abort
$ wasm-objdump --details --section=import target/wasm32-unknown-unknown/release/a_fancy_library.wasm | grep memory

 - memory[0] pages: initial=17 max=65536 shared <- env.memory

Now just have to figure out the bindings side with the thread transformation pass...

@mattgibb
Copy link
Author

Oh wait, looks like the bindings are picking up the variable now too! Amazing, so in summary for anyone reading this in future, you just have to add -C link-arg=--max-memory=4294967296 to your RUSTFLAGS if you'd like the maximum 4GB of memory. Thanks again for taking a look at this Alex and Crimson!

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

No branches or pull requests

2 participants