I don't have a useful answer, but a question and I can give an overview how my emulators work on the web:
Fist the question: What are you using the asyncify changes for? Just for "slicing up" the execution loop into frames, or also for other things? And here's how I do it in my emulators (https://floooh.github.io/tiny8bit/): - emulation and rendering happens through the "traditional" emscripten frame callback (via emscripten_request_animation_frame_loop(), this calls my own frame-callback for each frame), and everything runs single-threaded on the browser thread - in the frame callback I convert the frame duration to a number of ticks the emulator needs to run for this frame (e.g. with 60Hz frame rate and a 1 MHz system this would be around 16667 ticks), the measured frame time must be clamped to some sensible upper value, otherwise if the host system is too slow to run the emulation in realtime, it would run into a death spiral of longer and longer frames until the application freezes and is killed by the browser. - the emulation executes for this number of ticks, depending on the complexity of the emulated system this takes from under a millisecond up to 7 milliseconds emulators with a complex video system, like the C64 (on my mid-2014 13"MBP in Firefox, Chrome seems to be around 20% faster) - inside the emulation, everything runs "cycle-synced", all subsystem of the emulation (the emulated chips) do their work for one cycle, then the next cycle, and so on, all in very simple sequential and single-threaded C code. - the emulation updates a simple RGBA8 pixel buffer, and an audio sample buffer while it's executing - in each frame, the pixel buffer is copied into a WebGL texture and rendered as a quad, and when the intermediate audio sample buffer is filled up, it is forwarded to WebAudio (via ScriptProcessorNode, I know it's deprecated, but for this use case it works perfectly) - when all this is done, the frame callback function returns and the browser runtime is idle until the next frame starts I've been thinking about multi-threading, but haven't really had an idea how this would make sense. The user can't "see" anything that happens between presented frames, and the emulation itself runs bursts of cycles for one frame, the result is presented, control returns to the browser, and the whole thing repeats for the next frame. The native versions of the emulators work exactly the same btw, same code base. Platform abstraction happens through my sokol headers (https://github.com/floooh/sokol). So as I said, probably not all that helpful if js-dos works entirely differently, but I've arrived at this "application model" after quite a lot of trial and error (especially on the audio side), and it's now in a state for the last 2 years or so where I'm happy with it. It's remarkable that most things which improved the "perceived quality" on the web platforms where actually simplifications (also again mostly on the audio side). E.g. in the beginning I had a fairly complicated audio system in place where the emulation speed was tweaked by the audio system's buffer playback timing, hoping to eliminate audio artefacts because of gaps between buffers, but in the end the better solution was to just "trust" the frame callback being called at exactly the right time (which it seems to be across all platforms I'm testing), and generating the audio samples with the frequency expected by WebAudio, and then use ScriptProcessorNode to push new data to WebAudio. This works so well that I wonder why ScriptProcessorNode is deprecated. If you need to generate the audio data on the main thread, it's the perfect way to get the data into WebAudio. But I disgress :) Cheers, -Floh. On Wednesday, 15 January 2020 14:22:51 UTC+1, caiiiycuk wrote: > > Hi guys. I working on next version of js-dos, and I have some ideas > where to go. I have couple questions to see which way is better. > > Currently, js-dos is a WebAssembly binary (+asyncify changes) that > does emulation in 16ms frames, and stops with emscripten_sleep for > processing user input. So typical work flow is: > > 16ms emulation| <process user input> | 16ms emulation | <process user > input> | etc. > > Typically <user input> is empty, and performance is limited by browser > performance, and browser scheduler that stops emulation with > emscripten_sleep. > > My first question is: > 1. "Can I have any performance boost if I move emulation core inside > worker?" > > From my point of view it's not sens, because even in worker I should > stop emulations every 16ms to process messages and send updates to > page. Even If I do not account frames data (320x200 32bpp image), I > think performance will be same as in regular integration. Am I wrong? > > My second questing: > 2. "Is WASI perfromance is better than default WebView WebAsssembly > core?" (android/ios) > > One of my target is provide js-dos also on mobiles (android/ios) and I > think I can do it as is, or also I can do it with WASI. I think with > WASI clients can integrate js-dos in more ways, but what about > performance? Is it more preformant to use WASI instead of browser on > mobiles, or they are same? > -- 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/036493f2-32fd-4993-ac45-bf1f0da1a80e%40googlegroups.com.
