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

isolate mainloop into a webworker #124

Closed
mithrendal opened this issue Sep 4, 2022 · 6 comments
Closed

isolate mainloop into a webworker #124

mithrendal opened this issue Sep 4, 2022 · 6 comments

Comments

@mithrendal
Copy link
Contributor

all devices have at least two computing cores so why not separate the computing of the emulation into a separate worker thread and keep the main ui thread idle and therefore responsive?

since web workers and shared array buffers are supported by all major browsers as of today (shared array buffers can be used in safari 15.2 which is availabe since 9 months now).

See

https://caniuse.com/webworkers
https://caniuse.com/sharedarraybuffer

let us evaluate to use it for vAmigaWeb

two things are needed for this...

  1. enable COOP and COEP

how to do this I found this article which describes how to set these headers without touching the server which we can not because we host vAmigaWeb on github.io

http://stefnotch.github.io/web/COOP%20and%20COEP%20Service%20Worker/

  1. compiling vAmigaWeb with emsdk with use of web workers

https://emscripten.org/docs/api_reference/wasm_workers.html

and when we are done we can compare it performance wise with the current implementation...

@mithrendal
Copy link
Contributor Author

mithrendal commented Sep 4, 2022

I build as described in instructions above (2.)

and it complains

[ 99%] Linking CXX executable vAmiga.html
wasm-ld: error: --shared-memory is disallowed by SDL_atomic.o because it was not compiled with 'atomics' or 'bulk-memory' features.

it seems that the SDL2 port is not build with compiler/linker flag -sWASM_WORKERS

how to patch / add the missing flag ? We have to find the build script

I searched the system and found this ... maybe it is the build script and we can add the missing flag in it ?

emsdk/upstream/emscripten/tools/ports/sdl2.py

@mithrendal
Copy link
Contributor Author

mithrendal commented Sep 4, 2022

did a embuilder clear sdl2 to clear the sdl2 port

and patched the necessary flag into emsdk/upstream/emscripten/tools/ports/sdl2.py


command = [shared.EMCC,
                 '-sUSE_SDL=0',
                 '-c', os.path.join(ports.get_dir(), 'sdl2', SUBDIR, 'src', src),
                 '-o', o, '-I' + ports.get_include_dir('SDL2'),
                 '-O2', '-w','-sWASM_WORKERS']

now it compiles and links without error ...

when I run it says it doesn't know SharedArrayBuffer

vAmiga.js:566 Uncaught ReferenceError: SharedArrayBuffer is not defined
    at vAmiga.js:566:40

maybe now it needs COOP and COEP response headers?

@mithrendal
Copy link
Contributor Author

I did the step 1) to add the needed headers in the service worker

now it knows SharedArrayBuffer !

Next complaint is

Uncaught ReferenceError: _eglWaitClient is not defined
at vAmiga.js:6100:20

something is wrong with SDL ... I guess it can not be compiled with -sWASM_WORKERS...

maybe we should go another way
i.e. remove all sdl2 stuff from c++ and rewrite it in javascript

@mithrendal
Copy link
Contributor Author

all sdl2 program logic has been removed ...

a new web worker thread has been created

the vAmigaCore seems to like its new home and runs fine in the separate worker thread see here

image

the main thread is doing nothing now because I have still to reimplement the SDL render logic in javascript...

For this result I had to set the Amiga RTC RealTimeClock to none ... because emscripten had problems to access the timezone of the browser when build with the -sWASM_WORKERS option ... maybe a bug there we will see.

@mithrendal
Copy link
Contributor Author

mithrendal commented Oct 26, 2022

meanwhile have it running with a native javascript rendering logic as a replacement for the sdl2 rendering API, which was not compatible with web workers.

being in the mood of improving performance by exploiting the new possibilities of shared array buffers ... I found an interesting article about our current implementation of audio worklet sound processor in vAmigaWeb which is feed by postMessage calls from the main thread.

https://blog.paul.cx/post/a-wait-free-spsc-ringbuffer-for-the-web/

he simply claims that with shared array buffers one can replace the postMessage method and rely on a shared array buffer based ringbuffer. This should save processing time which is currently spent for the amiga audio stream.

here is a also a sample implementation using that sab based ringbuffer
https://ringbuf-js.netlify.app/example/main-thread-to-audioworklet/

@mithrendal
Copy link
Contributor Author

There is now a parameter in the make file which decides whether the vAmigaCore will run in a separate web worker or on the main thread.

#to build a worker built 
#1.set thread_type to "worker"
#2.go to the sw.js and set needs_shared_array_buffer=true
set(thread_type "worker")

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

No branches or pull requests

1 participant