design question about shared memory

42 views
Skip to first unread message

Shawn Riordan

unread,
Jan 30, 2020, 11:11:13 PM1/30/20
to emscripten-discuss
The first answer to this question:

describes how to take a global buffer in wasm and expose it as a typed array in javascript.
Where both the js and the cpp code and have random access to the same buffer.

Is there any volatility to the scope of the typed array?
What if the connection was made at the beginning of a session and kept throughout the lifetime of the program?
Would any memory end up being jostled about in the wasm that would cause the memory address to change?

Currently, I am passing an array of floats back and forth on a regular basis.  Lots of mallocs and frees.
It is attractive to me, to just do it once.  And so far, it works great.
But I am just wondering if there could be issues down the road.

J Decker

unread,
Jan 31, 2020, 9:37:03 AM1/31/20
to emscripten-discuss
On Thu, Jan 30, 2020 at 8:11 PM Shawn Riordan <craste...@gmail.com> wrote:
The first answer to this question:

describes how to take a global buffer in wasm and expose it as a typed array in javascript.
Where both the js and the cpp code and have random access to the same buffer.

Is there any volatility to the scope of the typed array?
Fortunately, JS threading model is single threaded, so there's no other thread to change it.
There are SharedArrayBuffers which can pass to worker threads, and have no volatile protection themselves. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer  'Updating and synchronizing shared memory with atomic operations'
 
What if the connection was made at the beginning of a session and kept throughout the lifetime of the program?
Would any memory end up being jostled about in the wasm that would cause the memory address to change?

I can't really answer this; like what happens when the heap needs to expand, but am curious if maybe there's a on-heap-change event that could be registered/handled.

Currently, I am passing an array of floats back and forth on a regular basis.  Lots of mallocs and frees.
It is attractive to me, to just do it once.  And so far, it works great.
But I am just wondering if there could be issues down the road.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/0df49606-82e9-4b02-bc44-83e7df70a1da%40googlegroups.com.

Alon Zakai

unread,
Jan 31, 2020, 6:16:00 PM1/31/20
to emscripte...@googlegroups.com
On Fri, Jan 31, 2020 at 6:37 AM J Decker <d3c...@gmail.com> wrote:


On Thu, Jan 30, 2020 at 8:11 PM Shawn Riordan <craste...@gmail.com> wrote:
The first answer to this question:

describes how to take a global buffer in wasm and expose it as a typed array in javascript.
Where both the js and the cpp code and have random access to the same buffer.

Is there any volatility to the scope of the typed array?
Fortunately, JS threading model is single threaded, so there's no other thread to change it.
There are SharedArrayBuffers which can pass to worker threads, and have no volatile protection themselves. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer  'Updating and synchronizing shared memory with atomic operations'
 
What if the connection was made at the beginning of a session and kept throughout the lifetime of the program?
Would any memory end up being jostled about in the wasm that would cause the memory address to change?

I can't really answer this; like what happens when the heap needs to expand, but am curious if maybe there's a on-heap-change event that could be registered/handled.


Memory growth is the one tricky case, yeah. The problem is that the JS typed array views become "invalid" in the sense that their size hasn't changed. So they can't load/store data above the size they were created with. To fix that, you need to create a new JS view and use that. (Emscripten does this automatically by checking if it is needed, which has some unavoidable overhead in JS, sadly.)

Currently, I am passing an array of floats back and forth on a regular basis.  Lots of mallocs and frees.
It is attractive to me, to just do it once.  And so far, it works great.
But I am just wondering if there could be issues down the road.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/0df49606-82e9-4b02-bc44-83e7df70a1da%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

Shawn Riordan

unread,
Jan 31, 2020, 11:47:09 PM1/31/20
to emscripten-discuss
I am not concerned about having the buffer need to change size.  I am satisfied by a fixed size.
My worry is what happens when the wasm code needs to grow its memory size because my C/C++ code malloc'd more and more memory.
What happens if they need to increase the size of the heap and everything gets reshuffled?

I imagine that the addresses of global variables won't change within the wasm module.
But the linkage to the javascript typed array might break.  And any attempt by the JS to access that array might lead to "bad things".

Maybe it is like J Decker said earlier.  I need some kind of notification of said memory-quake so that I can make the JS code re-link a new typed array to that static wasm buffer.
The question is:  What would that notification be?  And to whom?


On Friday, January 31, 2020 at 4:16:00 PM UTC-7, Alon Zakai wrote:
On Fri, Jan 31, 2020 at 6:37 AM J Decker <d3c...@gmail.com> wrote:


On Thu, Jan 30, 2020 at 8:11 PM Shawn Riordan <craste...@gmail.com> wrote:
The first answer to this question:

describes how to take a global buffer in wasm and expose it as a typed array in javascript.
Where both the js and the cpp code and have random access to the same buffer.

Is there any volatility to the scope of the typed array?
Fortunately, JS threading model is single threaded, so there's no other thread to change it.
There are SharedArrayBuffers which can pass to worker threads, and have no volatile protection themselves. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer  'Updating and synchronizing shared memory with atomic operations'
 
What if the connection was made at the beginning of a session and kept throughout the lifetime of the program?
Would any memory end up being jostled about in the wasm that would cause the memory address to change?

I can't really answer this; like what happens when the heap needs to expand, but am curious if maybe there's a on-heap-change event that could be registered/handled.


Memory growth is the one tricky case, yeah. The problem is that the JS typed array views become "invalid" in the sense that their size hasn't changed. So they can't load/store data above the size they were created with. To fix that, you need to create a new JS view and use that. (Emscripten does this automatically by checking if it is needed, which has some unavoidable overhead in JS, sadly.)

Currently, I am passing an array of floats back and forth on a regular basis.  Lots of mallocs and frees.
It is attractive to me, to just do it once.  And so far, it works great.
But I am just wondering if there could be issues down the road.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.

Brion Vibber

unread,
Feb 1, 2020, 12:46:40 AM2/1/20
to emscripten Mailing List
On Fri, Jan 31, 2020, 8:47 PM Shawn Riordan <craste...@gmail.com> wrote:
I am not concerned about having the buffer need to change size.  I am satisfied by a fixed size.
My worry is what happens when the wasm code needs to grow its memory size because my C/C++ code malloc'd more and more memory.
What happens if they need to increase the size of the heap and everything gets reshuffled?

I imagine that the addresses of global variables won't change within the wasm module.
But the linkage to the javascript typed array might break.  And any attempt by the JS to access that array might lead to "bad things".

In WebAssembly builds, old TypedArray views into the heap will continue to point at the right place and may still be used after a growth. A WebAssembly.Memory is special in that it is backed by an explicitly growable buffer with reserved virtual memory address space for it to increase.

(I think when using memory growth with JS builds, your views will become stale after a growth event, because growth requires creating a new backing ArrayBuffer and copying old data into it.)

If you're using memory growth with Wasm pthread builds, the important thing is to make sure your TypedArray views are created using an up to date source. This should always be the case using JS compiled into the module that uses wasmMemory.buffer, or that uses HEAP* variables directly to make subarrays. The former is always up to date, and the latter are kept up to date by a compile time transformation to a safe accessor function that checks wasmMemory.buffer internally.

In particular avoid accessing Module.HEAPU8 and friends from outside the module, as these might be out of date after a growth from another thread.


Maybe it is like J Decker said earlier.  I need some kind of notification of said memory-quake so that I can make the JS code re-link a new typed array to that static wasm buffer.
The question is:  What would that notification be?  And to whom?

There's an internal runtime function that's called to update the views, but that's only needed to make the new address space visible in the views. There's also no way to synchronously propagate that to every thread -- hence the special accessor functions in the JS runtime to guard usage of HEAP* vars.

-- brion



On Friday, January 31, 2020 at 4:16:00 PM UTC-7, Alon Zakai wrote:
On Fri, Jan 31, 2020 at 6:37 AM J Decker <d3c...@gmail.com> wrote:


On Thu, Jan 30, 2020 at 8:11 PM Shawn Riordan <craste...@gmail.com> wrote:
The first answer to this question:

describes how to take a global buffer in wasm and expose it as a typed array in javascript.
Where both the js and the cpp code and have random access to the same buffer.

Is there any volatility to the scope of the typed array?
Fortunately, JS threading model is single threaded, so there's no other thread to change it.
There are SharedArrayBuffers which can pass to worker threads, and have no volatile protection themselves. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer  'Updating and synchronizing shared memory with atomic operations'
 
What if the connection was made at the beginning of a session and kept throughout the lifetime of the program?
Would any memory end up being jostled about in the wasm that would cause the memory address to change?

I can't really answer this; like what happens when the heap needs to expand, but am curious if maybe there's a on-heap-change event that could be registered/handled.


Memory growth is the one tricky case, yeah. The problem is that the JS typed array views become "invalid" in the sense that their size hasn't changed. So they can't load/store data above the size they were created with. To fix that, you need to create a new JS view and use that. (Emscripten does this automatically by checking if it is needed, which has some unavoidable overhead in JS, sadly.)

Currently, I am passing an array of floats back and forth on a regular basis.  Lots of mallocs and frees.
It is attractive to me, to just do it once.  And so far, it works great.
But I am just wondering if there could be issues down the road.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/39709d61-2706-4b33-b1d9-bc92e90dd352%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages