Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory limits in webassembly

What will be the policy of memory allocation limits for webassembly programs?

Will the current (hard) javascript engine memory limits be inherited? E.g. will be possible to write real applications that needs more than a few hundred of megs of memory?

Current browser policies on memory allocation on javascript pose hard constraints to what is actually doable in a browser. Speed is no more a problem with emscripten/asm.js and jit compiling, but the memory constraints make hard or impossible to build any serious application in a browser.

See for example http://www.meshlabjs.net, the run-in-browser version of the MeshLab mesh processing system. With respect to the desktop application the main limit is that, in the javascript based version, large 3D models cannot be loaded for the intrinsic limits on allocation imposed by the js engine of the browsers.

like image 758
ALoopingIcon Avatar asked Nov 04 '16 08:11

ALoopingIcon


People also ask

What is WebAssembly memory?

The WebAssembly. Memory object is a resizable ArrayBuffer or SharedArrayBuffer that holds the raw bytes of memory accessed by a WebAssembly. Instance . Both WebAssembly and JavaScript can create Memory objects.

Is WebAssembly memory safe?

WebAssembly (Wasm) is a next-generation portable compi- lation target for deploying applications written in high-level languages on the web. In order to protect their memory from untrusted code, web browser engines confine the execution of compiled Wasm programs in a memory-safe sand- box.

Is Wasm 32 bit or 64 bit?

WebAssembly has only four value types: i32 – 32-bit integers. f32 – 32-bit floating point numbers. i64 – 64-bit integers.

How much faster is WebAssembly than JavaScript?

In one recent study, a developer discovered Wasm is faster than JavaScript across three desktop browsers on desktop computers and smartphones. Wasm is 1.15-1.67 times faster than JavaScript on Google Chrome on a desktop. Wasm is 1.95-11.71 times faster than JavaScript on Firefox on a desktop.


Video Answer


3 Answers

WebAssembly has a WebAssembly.Memory object and the binary has a memory section. Through these, a developer provides educated guesses about minimum and maximum memory usage, the VM then allocates at least the minimum (or fails). A developer can then, at runtime, ask for more through grow_memory which tools like Emscripten will use under the hood of malloc (it's somewhat similar to sbrk).

For asm.js it was difficult to know how the ArrayBuffer was going to be used, and on some 32-bit platforms you often ran into process fragmentation which made it hard to allocate enough contiguous space in the process' virtual memory (the ArrayBuffer must be contiguous in the browser process' virtual address space, otherwise you'd have a huge perf hit). You'd try to allocate 256MiB and sometimes hard-fail. This got extremely difficult if the browser wasn't multi-process, because all the other tabs are competing for 32 bits of virtual address space. Browsers were a bit silly a few years ago, they got better, but 32 bits ain't much to go around.

WebAssembly is backed by WebAssembly.Memory which is a special type of ArrayBuffer. This means that a WebAssembly implementation can be clever about that ArrayBuffer. On 32-bit there's not much to do: if you run out of contiguous address space then the VM can't do much. But on 64-bit platforms there's plenty of address space. The browser implementation can choose to prevent you from creating too many WebAssembly.Memory instances (allocating virtual memory is almost free, but not quite), but you should be able to get a few 4GiB allocations. Note that the browser will only allocate that space virtually, and commit physical addresses for the minimum number of pages you said you need. Afterwards it'll only allocate physically when you use grow_memory. That could fail (physical memory is about as abundant as the amount of RAM, give or take swap space), but it's much more predictable.

An implementation can pull a similar trick on 32-bit platforms (over-commit but keep PROT_NONE and not physically allocated), assuming fragmentation allows, but that's up to the implementation and how it think this affects ASLR. Realistically it's hard to find memory when there's not much to go around, but virtually and physically.

WebAssembly is currently specified as an ILP32 process: pointers are 32 bits. You're therefore hard-limited to 4GiB. We may add wasm64 in the future.

like image 68
JF Bastien Avatar answered Oct 21 '22 17:10

JF Bastien


I summarize a bit the above answers, the comments and a bit more of googling done around; there are two issues that prevent using WebAssembly for being used projects that require a significant amount of memory:

  • current WebAssembly implementations follow a 32bit addressing space model, so no hope of using more than 4gb of mem until wasm64 is out (proposal overview).
  • browsers arbitrarily decide what is the amount of memory given to a page. This is (mostly) for security reason because people love to think to web pages as something more "safe" than desktop applications.

Hopefully both issues can be solved. I hope that browsers will expose those limits in a explicit way; just like when a page request to use your camera it is notified, you should simply notify the user that a page want a ton of memory and block it until you answer.

like image 44
ALoopingIcon Avatar answered Oct 21 '22 18:10

ALoopingIcon


Relevant proposals (see their current stages here):

Multiple Memories

This proposal adds the ability to use multiple memories within a single Wasm module. In the current version of Wasm, an application can already create multiple memories, but only by splitting things up into multiple modules. A single module or function cannot refer to multiple memories at the same time. Consequently, it is not possible to e.g. efficiently transfer data from one memory to another, since that necessarily involves an individual function call into a different module per value.

https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md

Memory64

This page describes a proposal to support linear memory of sizes larger than 2^32 bits. It provides no new instructions, but instead extends the currently existing instructions to allow 64-bit indexes.

WebAssembly linear memory objects have sizes measured in pages. Each page is 65536 (2^16) bytes. In WebAssembly version 1, a linear memory can have at most 65536 pages, for a total of 2^32 bytes (4 gibibytes). In addition to this page limit, all memory instructions currently use the i32 type as a memory index. This means they can address at most 2^32 bytes as well.

https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md

like image 33
joe Avatar answered Oct 21 '22 19:10

joe