I think what's going on here is that subarray() is another view on the same
backing buffer. While slice() creates a new buffer for you.

For example:

> x = new Int8Array(10)
Int8Array [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
> x.buffer.byteLength
10
> x.subarray(1, 3).length
2
> x.subarray(1, 3).buffer.byteLength
10

So the length is small, but the buffer behind it is still the full original
size.

> x.slice(1, 3).length
2
> x.slice(1, 3).buffer.byteLength
2

But a slice() has the right buffer size.

In other words, when you pass views on HEAP8, the browser is copying the
entire buffer behind that, which is big - all of memory. You need to make a
new buffer of the right size.

Note that you may be able to make this even more efficient using transfer,

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer


On Mon, Apr 20, 2020 at 7:48 AM Александр Гурьянов <[email protected]>
wrote:

> Hi. I am doing worker backed for js-dos project, and now it pass all
> tests that was made for default backend too. But I found inexplicable
> behaviour. Worker process periodically sends updates for canvas. This
> is code that I used:
>
> ```
>                 Module.sendMessage = function (name, props) {
>                     postMessage({
>                                  name,
>                                  props
>                         });
>                 };
>
> ...
>
> #ifdef EMSCRIPTEN
>     EM_ASM(({
>                 Module.frame_update_lines = [];
>             }));
>
>     for (uint32_t i = 0; i < count; ++i) {
>         uint32_t start = lines[i * 3];
>         uint32_t count = lines[i * 3 + 1];
>         uint32_t offset = lines[i * 3 + 2];
>         EM_ASM(({
>                     Module.frame_update_lines.push({
>                         start: $0,
>                         heapu8: Module.HEAPU8.subarray($1, $1 + $2)
>                         });
>                 }), start, (char*) rgba + offset, sizeof(uint32_t) *
> count * frameWidth);
>     }
>
>     EM_ASM(({
>                 if (Module.frame_update_lines.length > 0) {
>                     Module.sendMessage("ws-update-lines",
> Module.frame_update_lines);
>                 }
>                 delete Module.frame_update_lines;
>             }));
> #endif
> ```
>
> So, message is array of rgba data that need to be drawn on canvas.
> It's sort of dirty rects that need be updated.
>
> When I run it results are terrible, both in Chrome and FF fps is near
> 11-12 FPS, when for non-worker version it is 55-60.
>
> I tried a lot, and problem place as expected is sendMessage, lot of
> time is spent here. BUT, by chance I tried to replace
> Module.HEAPU8.subarray with Module.HEAPU8.slice and magic is happened.
> With Module.HEAPU8.slice FPS for worker is 55-60 both in Chrome and
> FF.
>
> It's very good news for me, but I don't understand why I have this
> performance boost. I thought that subarray should be faster then
> slice, because as said it works on the same ArrayBuffer when slice is
> copying it.
>
> Why slice is faster then subarray?
>
> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/emscripten-discuss/CAKOm%3DVES80yNV-mePExaQGrY-TRWe-c2%3DY89TMEOrdOj%3DFq-9w%40mail.gmail.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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/emscripten-discuss/CAEX4NpTgAQzApQCdsFOmWJWQCxNVxbRX2iZHoJen5%2Bc1fs%2BFxw%40mail.gmail.com.

Reply via email to