Experimenting with web workers

Last week I was experimenting with web workers, trying to separate rendering related tasks from the cpu emulation itself. It was a bittersweet experience.

A bit of context:

Webworkers allows you to do multithreading without all the complexities of traditional threads: mutex, semaphores, locks. In fact, do proper multithreading is hard and prone to errors, and the worst errors: errors that happens sometimes and are not consistently reproduced. Also sometimes you can just reproduce them when the system is overloaded and thus the worst moment for the bug to trigger.

So open web’s workers, actionscript workers or dart’s isolates try to avoid most of those problems. How? There is no shared memory. Two workers can’t access the same memory. Each one has its own heap and they are isolated. So you are passing messages between each other or even transferring data withot copying; in the case of web workers, you can transfer ArrayBuffer objects without copying them.

Even when each worker can work on its own, and emit messages whenever they want. It is always preferred to have a main worker and send tasks to others, because of simplicity. Ideally you are using workers for intensive tasks like decompression, decoding, and so on. MediaEngine is ideally for this. You can decode audio and video there in a request/response/task fashion. Also you can do that for crypto and zlib compression.


Next version: HUGE graphics speedup: Valhalla Knights at 60fps + ffmpeg based media engine

I have been working on some optimizations. Basically I have mostly rewritten the gpu engine and have improved a lot the performance. In a i5@2.2ghz with a Intel HD Graphics 5000, Valhalla Knights works most of the time at full speed. Also I have been working on a ffmpeg based media engine for decoding audio and video (WIP).


New added optimizations

I have already done some optimizations I planed some time ago.

Now the compiler is creating bigger functions. Also I have reduced the native function calling overhead, and the overhead of function lookup.

Here the results:

Loops and function calls are now much much faster than before, and that will mean faster running. In chrome the improvement is not that huge like with firefox. Firefox was performing so bad because of the function lookup that was lightning fast in chrome. Now that the function lookup is cached and not that frequent, there is not so much difference between chrome and firefox (regarding to cpu). Still the overall chrome is faster than firefox.

Also I have added a new benchmark with this (the v2): http://benchmark.jspspemu.com/v2/ You can still access the previous (v1): http://benchmark.jspspemu.com/v1/


Next cpu optimizations

I have resumed the work of the emulator. Now I plan to make some optimizations to be able to reach a good speed in mobile.

Now most generated functions are like this:

function state(state) {
var expectedRA = state.getRA();
/*08804338*/ /*    lui */  state.gpr[8] = 0x08820000;
/*0880433c*/ /*   addu */  state.gpr[6] = (0 + 0);
/*08804340*/ /*   addu */  state.gpr[3] = (0 + 0);
/*08804344*/ /*  addiu */  state.gpr[8] = (state.gpr[8] + -20752);
/*08804348*/ /*  addiu */  state.gpr[7] = (0 + 5);
/*0880434c*/ /*   addu */  state.gpr[4] = (state.gpr[8] + 0);
/*08804350*/ /*    lui */  state.gpr[2] = 0x00500000;

while (true) {
/*08804354*/ /*     lh */  state.gpr[5] = state.lh(((state.gpr[4] + 0) | 0));
/*08804358*/ /*  addiu */  state.gpr[2] = (state.gpr[2] + -1);
/*0880435c*/ /*  addiu */  state.gpr[4] = (state.gpr[4] + 2);
/*08804360*/ /*    bne */  state.BRANCHFLAG = (state.gpr[2] != 0);
state.BRANCHPC = 0x08804354;
/*08804364*/ /*   addu */  state.gpr[3] = (state.gpr[3] + state.gpr[5]);
if (state.BRANCHFLAG) { state.PC = state.BRANCHPC; } else { state.PC = 0x08804368; }
if (!state.BRANCHFLAG) return;

Just a single loop, using the gpr Int32Array directly, and giving up soon. No calling or jumping other functions either. So it is slow. Faster than a pure interpreter, but much slower than a proper dynarec.

How to optimize this?


Benchmark + headless running (using node.js)

I have created a benchmark that allows to test several javascript engines. You can check it here: http://benchmark.jspspemu.com/v1/

Also now you can run the benchmark from node:

node jspspemu_headless.js data/benchmark/benchmark.prx

This allow you to run any PSP program and see the output it produces using the stdout, also the host process exists when the guest exists. This should run with any node version in any supported host architecture including arm, mips or x86/x64.


Embedding + New GUI + encrypted executable loading + travis-ci

Since my last post, I have worked a bit more in the emulator. Now it has a new GUI. Also I have been working in decoding encrypted executables. And today I put jspspemu on travis-ci. I am using mocha-phantomjs for running tests. You can see the status of the build with a badge included in github and this blog.

Also I have included a share button that allows you to embed easily demos and games:


Valhalla Knights working

Since last week I have been working on sasCore, gpu and vfpu. Today’s version is capable of running Valhalla Knights. Still not running at full speed but it is getting closer. After lazily updating webgl state, and making some improvements in vfpu, it should start running at full speed on modern computers.

  • Implemented sasCore (sound in games like Valhalla Knights and Lumines)
  • Gpu speedups and fixes
  • Vfpu fixes


Tools for debugging the emulator

While developing the emulator I needed to debug stuff. Besides the pspautotests project that allowed me to verify some behaviours, I need to stop the execution of the emulator in several places, and to trace stuff. Also I needed to debug webgl and to detect which parts of the emulator to optimize.

The simplest way of debugging:

console.log(), console.warn(), console.error()


Updated 2014-05-15 - Lumines

In a couple of days I have implemented most of the psp vfpu, still misses some functions and some of them require fixes. Also I have performed some general fixes.
Today’s version got Lumines ingame (without sound (no sasCore yet)) and some other games like Breath of Fire 3; others start showing something. Still slow as hell, and with lots of graphical glitches, but a good first step.

I have created issues for the biggest+important parts of the emulator missing here to get most games working: https://github.com/soywiz/jspspemu/issues

  • vfpu (almost complete)
  • module loading
  • mpeg decoding
  • kirk and encrypted prx decoding
  • sasCore


First version supporting Puzzle Bobble

This version, allows to play Puzzle Bobble within modern browsers without plugins. It should work on windows, linux, mac… It now supports saving, audio with atrac3+ and displays bezier curves (still hacky) and should work on mobile (though still a bit slow).

It is know to work on Chrome, Opera, Firefox, IE11. And currenly don’t work on Safari.

You can test the lastest stable version as always here: http://jspspemu.com/


Streaming PSP games, embedding and CORS

One of the strengths of this emulator is that it is able to stream large games, including zip files, isos, csos, eboots, etc.

So it is possible for example to stream the psp homebrew reminiscence, a port of flashback, Doom, abuse or kaiten patisser.

You can test them here (some could be broken in master release):
http://jspspemu.com/#http://games.jspspemu.com/Doom.zip (3MB)
http://jspspemu.com/#http://games.jspspemu.com/reminiscence.zip (95MB)
http://jspspemu.com/#http://games.jspspemu.com/abuse.zip (19MB)
http://jspspemu.com/#http://games.jspspemu.com/UraKaitenPatissierPSP.zip (13MB)

It won’t download the whole file, but will read relatively small chunks (usually 128KB) (and perform buffering) when required. So the game will start immediately, won’t require large local storages and the bandwidth used will be limited.

This will allow homebrew developers to allow people to play their games online. Or even embedding it in an iframe.

In order to be able to do this, you need to use CORS (Cross-origin resource sharing)


Viability of a javascript psp emulator

So, It is viable to create a javascript emulator that will run at full speed? The answer is yes.

Results greater than 100% mean that will work faster than on a real PSP (in theory):


subscribe via RSS