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

Improve support of embedded systems with limited RAM #1089

Closed
vshymanskyy opened this issue Jan 31, 2020 · 8 comments
Closed

Improve support of embedded systems with limited RAM #1089

vshymanskyy opened this issue Jan 31, 2020 · 8 comments

Comments

@vshymanskyy
Copy link

Many embedded devices currently cannot afford to allocate even a single page of Linear Memory (64KB). In Wasm3 engine, we set memoryLimit to the actual amount available. This way, we allocate a fraction of a page (usually 2..16 Kb), and trap on OOB access attempts.

The AssemblyScript allocator assumes that the full page is accessible and performs OOB access during initialization, which renders it unusable in this situation.

I think it would be great to have something similar to memoryLimit flag for asc.
Another option would be to support pages <64Kb, however this is not compatible with current wasm spec. This is also discussed here here and here

Let me know what you think.

@dcodeIO
Copy link
Member

dcodeIO commented Jan 31, 2020

I guess it should be rather trivial to add such a limit, but I wonder how much of a benefit this would be.

For instance, regarding

The AssemblyScript allocator assumes that the full page is accessible and performs OOB access during initialization, which renders it unusable in this situation.

How it currently works is that the TLSF allocator reuses whatever memory it can, and only if it needs more memory than what is in the free list it increases the limit (within a page). There are additional mechanisms in place that do not apply here, like performing a garbage collection before requesting more pages, which is only relevant if cyclic structures are used and growing pages is applicable in the first place (no cyclic structures means a collection is a nop). In a carefully designed program, the full/half runtimes would not unnecessarily fill up memory but instead be very eager to free up memory as soon as possible. Due to its already eager implementation, a limit would be of limited use here I guess.

The stub/none runtime is a bit different in that it simply fills up memory, with no sophisticated means of freeing memory (except undoing the top-most block). Even if we'd introduce a limit, one would quickly run into a runtime out of memory error with it due to trading sheer simplicity for memory usage. When I read the above paragraph, I immediately thought of the stub/none runtime being used, is that correct?

It might well be that the full/half runtime is too sophisticated (mostly thinking code size and perhaps bookkeeping structures in memory) and the stub/none runtime too dumb (thinking wasting memory) for IOT, in which case we should look into a third runtime providing some sort of middle ground?

Edit: Oh, wait, I totally missed that TLSF adds the initial amount of pages to its free list. That's where a limit would come into play, so it only adds some of the first page initially. Going to look into that.

@vshymanskyy
Copy link
Author

@dcodeIO half runtime is in use, but i get OOB access immediately during module execution.
I can investigate further to find out what exactly happens (up until now I was only guessing)

@dcodeIO
Copy link
Member

dcodeIO commented Jan 31, 2020

I see, yeah. Made a few steps into that direction in the PR above. Let me know :)

@vshymanskyy
Copy link
Author

Thanks, will check it out 😎

@vshymanskyy
Copy link
Author

@dcodeIO just tried it out.
Whenever I set --lowMemoryLimit i get "Low memory limit exceeded by TLSF bookkeeping" (I tried 2048, 1048576, 1000000000).
Here's the exact script I'm trying to build: https://github.com/wasm3/wasm3-arduino/tree/master/examples_pio/Wasm_Advanced/wasm_apps/assemblyscript

@dcodeIO
Copy link
Member

dcodeIO commented Jan 31, 2020

Turned out we can't use a static error there. Changed it so the module will trap if bookkeeping exceeds the limit already.

@vshymanskyy
Copy link
Author

@dcodeIO thanks for a quick fix. It really helped with my initial problem, however is not fully working in some scenarios. Will need further investigation

@dcodeIO
Copy link
Member

dcodeIO commented May 28, 2020

Closing this issue as part of 2020 vacuum because the initial implementation has landed meanwhile. It is likely that it isn't yet optimal, so I suggest opening a new issue mentioning the concrete problems encountered so we can keep track of things more easily.

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

No branches or pull requests

2 participants