Skip to content
James Baicoianu edited this page Aug 28, 2014 · 16 revisions

JSMESS/JSMAME runs very well.... as long as you have a ridiculously fast system and the emulation is ridiculously fast as well (hundreds of percentage points faster than the original system).

It's a lot better than it used to be; the Colecovision emulation in JSMESS ran at 14% when it first got working - now it generally hits 100% on almost any system. But if the emulation is just a few times faster than the original, the chances of the JSMESS version being just a little too slow is pretty high.

This is an attempt to begin to understand where speed can be gained. Since JSMESS is an emscripten-compiled version of a program, there are some possibilities of gaps and missed opportunities that could be improved.

  • JSMESS has some really really huge switch statements in it. There's possible speed to be gained by dealing with the massive switch inside the JSMESS program. A programmer has come forward to look into a solution where this switch statement could be modified to run faster in browsers>

    • Issue #74 is an example of one solution for a different project; perhaps those learnings could apply to JSMESS.
  • The way that JSMESS was converted to run asynchronously seems inefficient. MAME was designed to run its main loop repeatedly until the user exits, using usleep to return time to the OS, which does not work in a web browser context. The current solution is basically a hack that runs all the initialization code and then switches to a requestAnimationFrame callback that tries to run 1/60th of a second worth of emulation (see js_main_loop and js_set_main_loop in src/emu/machine.c).

    • Profiling the results suggests that this method is interacting badly with the existing throttling code in src/emu/video.c (e.g. throttle_until_ticks()) as Emscripten converts the sleeps into busy waits that waste CPU.
    • At other times, it appears that the browser is idle even though the emulation is not running at full speed. Coming up with a method for using this downtime more efficiently would cause a notable increase in speed.
  • WebGL and audio optimizations may improve performance.

    • Issue #45 details the differences between MESS' native audio formats and Web Audio's. Changing MESS may or may not improve Web Audio performance, but we won't know until someone digs into it and/or tries it.
    • Issue #73 is the same, for WebGL rendering v. the 2D canvas rendering currently used.
  • Exception handling in Emscripten is slow. The MESS/MAME core uses C++ exceptions in a few places. In a native compile this does not add any overhead unless the exception is thrown, but the Emscripten implementation of exceptions adds the overhead regardless. We are using the DISABLE_EXCEPTION_CATCHING=2 and EXCEPTION_CATCHING_WHITELIST options of Emscripten but there still seems to be a negative performance impact.

    • It may be possible for Emscripten to handle this more efficiently although it would likely require changes to JavaScript engines and/or the asm.js spec.
    • Alternatively it may be possible to rewrite the relevant areas of the core not to use exceptions, although this would need to be done in such a way as to be acceptable for upstream submission.
  • JSMESS runs in a single core. It's not likely to be changed, between the way Javascript and most browsers work. So unless something changes externally, JSMESS is only as fast as one core of a machine.

    • MESS/MAME has a basic multithreading option, disabled by default, which can for example do the final blit in a separate thread from the rest of the emulation. However due to the limitations of JavaScript and Emscripten it is not possible to compile this functionality to JavaScript at present. (Web Workers do not have shared state which is necessary to emulate C++ threads.) It may be possible to rewrite this functionality using Web Workers.
    • Web Workers might also be a solution for efficiently running multiple instances of JSMESS on a single page/site. Work has begun on this, and is being documented in Issue #101

More to be added.