-
Notifications
You must be signed in to change notification settings - Fork 2
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
Sub-proposal: memory.discard
#6
Comments
Thanks @bvisness for filing this! The V8 prototype currently has an API only function for Explicit cc for @dschuff because we had previously discussed having a couple of different toolchain flags that support both the approaches so this can be experimented with. There's a few questions in this design space that might be interesting to discuss:
|
+1 to page-alignment for these operations. I don't think we want to introduce a new instruction that is redundant with [1] AFAICT, an engine could transparently drop pages for very large |
Yes, it's completely valid to implement this as filling the whole region with zero bytes. This proposed design does not change the length of the memory at all, or introduce regions that will trap when accessed. Behind the scenes, we're using OS specific API's which 'essentially' replace the OS pages with lazy-allocated zero pages. This reduces memory pressure on the system until the pages are accessed again. On some platforms the pages are re-allocated on read, others on write. This is pretty platform specific, and the most details are on the linked docs.
I agree that keeping the base/length byte lengths aligned to wasm pages is simplest. The only argument I could see for relaxing this somehow is if wasm pages are too big that users rarely ever have that much address space unused and ready to free, especially with heap fragmentation. In that case, it'd be beneficial to have some lower granularity that is closer to the OS page size. But this has other issues and we shouldn't consider this unless we hear it would help from users.
If the base/length are not aligned to wasm page size, then we emit a WebAssembly.RuntimeError. We do this for both the instruction and JS-API entry points. |
We have now implemented memory.discard for shared memories in SpiderMonkey. The document has been updated with our findings and recommendations, and our demo now supports shared memories as well. Windows makes this difficult, since none of the available virtual memory APIs directly allow us to replace working set pages with demand-zero pages in a single call. However, using At this point, we'll try out our memory.discard instruction in some real programs and see what kinds of improvements we get. |
memory.discard
To address a comment by @BlobTheKat on WebAssembly/design#1543:
The question with such a strategy is whether the memory would initially be committed or not. (This applies primarily to Windows, but also to systems with overcommit disabled.) By "committed" I generally mean "mapped as read-write", such that accessing the memory will not cause a signal or exception. If the memory is committed by default, then physical memory use stays low (RSS), but the system may still fail the memory allocation due to a system commit limit. This limit can actually be quite low; on Windows I believe it defaults to three times the size of physical memory. That means that committing 4GB on a system with 4GB of RAM would require a full third of the system-wide commit limit, and is likely to fail. On mobile in particular these limits can be drastically lower still. On the other hand, if memory is not committed by default, the 4GB reservation is likely to succeed, but accessing these pages now triggers an exception. If you wish to preserve wasm's current semantics and get zeroes instead of trapping, then you need to implement "software page faults", committing pages inside a signal handler and resuming execution of your wasm program manually. This is not impossible, but certainly is clumsy, and likely considerably slower than letting the operating system handle the page fault. @lukewagner has suggested that you could pair I think that using the full 4GB address space (or larger address spaces with memory64) would be best done with an explicit |
I do see what you mean by clumsy. The performance cost on the other hand is not significant: exceptions do not happen frequently, and the handler simply hands back to the OS to add the page. The only overhead over page allocation the traditional way is the intermediate user-space step that immediately hands back to the OS |
Exceptions would happen frequently in this scheme: every time a page is touched for the first time. That said, at this point we do still need to measure the overhead. |
This issue tracks discussion of the
memory.discard
sub-proposal. This proposal is one possible component of the eventual Memory Control MVP. Please make sure to read the full sub-proposal document.This issue previously tracked discussion of the SpiderMonkey team's proposal of an older sketch of
memory.discard
. To avoid losing context, this issue has been repurposed. The original discussion starts below.We on the SpiderMonkey team have created a prototype of
memory.discard
from this proposal. We've also created a document exploring the design space and the results of our research.https://docs.google.com/document/d/131BCKkMSdKCeU51XJ52mIy5O4i60CIGMopSh8aWNQG8/edit?usp=sharing
Our prototype is available behind a flag in Firefox Nightly - you can try it here. It does not yet support shared memories, as we’re still researching how to handle this on Windows.
I look forward to everyone's comments and suggestions! This instruction feels good to us so far.
The text was updated successfully, but these errors were encountered: