Birch-san / liquidfun-play-2

28 stars 3 forks source link

Minimise js/wasm #3

Open danbri opened 2 years ago

danbri commented 2 years ago

minimize JS->wasm calls in favour of accessing Emscripten heap directly

Where do you do this? Have you tried removing this hack?

Birch-san commented 2 years ago

https://twitter.com/danbri/status/1490437384600801281?s=20&t=G-rHvT6XxiDF92-vv3VZIA

https://threadreaderapp.com/thread/1490464691537203202.html

Mostly I mean "avoid wrapPointer(), because it allocates small objects, which when freed create garbage that necessitate a GC pause, resulting in framerate stutter".

I haven't tried removing that (in the code linked in that Twitter thread, you can see in the commented-out code above it what the more idiomatic call would look like).

tbh I think wrapPointer might not be so bad if the object has a long lifetime (i.e. exists for a few seconds so we get to re-use the wrapped on subsequent frames).

But honestly I think this is a deficiency in Emscripten's design of how to reify heap pointers into user-friendly JS abstractions. There's no need to allocate instances at all; you could just have a singleton class (e.g. b2Vec2) and give it a method to become a view over a pointer. So a single instance could be re-purposed rather than allocating one instance per heap pointer.

Birch-san commented 2 years ago

And yeah I'm not too worried about the cost of invoking Emscripten's binding methods to invoke WASM calls to lookup attributes of objects on the heap (as opposed to doing pointer arithmetic to grab it directly from the heap).

Because nowadays it's fast (it wasn't fast during liquidfun.js days, hence they needed to rely on pointed arithmetic and hence made a bunch of lookup helpers to assist with that)
https://hacks.mozilla.org/2018/10/calls-between-javascript-and-webassembly-are-finally-fast-%F0%9F%8E%89/

So long as the JIT can inline across language boundaries, there should be no perf difference between using WASM calls to lookup heap memory versus using pointer arithmetic to indirect into the heap.

Birch-san commented 2 years ago

The biggest perf win that's being left on the table is that liquidfun wrote some faster particle algorithms for the Android distribution, handwriting NEON SIMD assembly. This cannot be automatically converted into WASM SIMD (you'd need to understand what the assembly algorithm is trying to do, and handwrite a port of it -- in WASM assembly or in C++ -- using WASM SIMD intrinsics). I tried but WASM's intrinsics are so different from NEON's that I couldn't understand how to rewrite it.

But theoretically that could speed up particle simulation by up to.. 4x? because you could process four 32-bit data in an instruction which accepts 128-bits simultaneously.

danbri commented 2 years ago

Thanks for all that! I don't want to leave an open issue dangling but it would be good to keep these notes around somehow. Feel free to close it anyway!

danbri commented 2 years ago

Thank you! I did remember us discussing it but failed to find the Twitter thread.

On Sat, 2 Jul 2022 at 12:51, Birch-san @.***> wrote:

https://twitter.com/danbri/status/1490437384600801281?s=20&t=G-rHvT6XxiDF92-vv3VZIA

https://threadreaderapp.com/thread/1490464691537203202.html

Mostly I mean "avoid wrapPointer(), because it allocates small objects, which when freed create garbage that necessitate a GC pause, resulting in framerate stutter".

I haven't tried removing that (in the code linked in that Twitter thread, you can see in the commented-out code above it what the more idiomatic call would look like).

tbh I think wrapPointer might not be so bad if the object has a long lifetime (i.e. exists for a few seconds so we get to re-use the wrapped on subsequent frames).

But honestly I think this is a deficiency in Emscripten's design of how to reify heap pointers into user-friendly JS abstractions. There's no need to allocate instances at all; you could just have a singleton class (e.g. b2Vec2) and give it a method to become a view over a pointer. So a single instance could be re-purposed rather than allocating one instance per heap pointer.

— Reply to this email directly, view it on GitHub https://github.com/Birch-san/liquidfun-play-2/issues/3#issuecomment-1172885681, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABJSGOXMS4GUOW4KXIZ5XLVSAUMBANCNFSM52O5UVJQ . You are receiving this because you authored the thread.Message ID: @.***>