v86 icon indicating copy to clipboard operation
v86 copied to clipboard

Improve performance of v86 in Web Worker vs. Window

Open humphd opened this issue 7 years ago • 0 comments

I want to run v86 in a Worker, and it works; however, it's quite a bit slower than running the identical code in a window, especially for the initial boot.

I haven't done much profiling yet, but I wanted to discuss one simple thing that could be done throughout the code: prefer self (i.e., window.self) to window such that code paths for workers vs. windows are reduced.

Here are some examples of places where this would help:

src/lib.js

if(typeof window !== "undefined" && window.crypto && window.crypto.getRandomValues)
{
    let rand_data = new Int32Array(1);

    v86util.has_rand_int = function()
    {
        return true;
    };

    v86util.get_rand_int = function()
    {
        window.crypto.getRandomValues(rand_data);
        return rand_data[0];
    };
}
else
{
    v86util.has_rand_int = function()
    {
        return false;
    };

    v86util.get_rand_int = function()
    {
        console.assert(false);
    };
}

Worker contexts in most browsers have access to self.crypto.getRandomValues.

src/cpu.js

// Some functions must not be inlined, because then more code is in the
// deoptimized try-catch block.
// This trick is a bit ugly, but it works without further complication.
if(typeof window !== "undefined")
{
    window["__no_inline_for_closure_compiler__"] = [
        CPU.prototype.exception_cleanup,
        CPU.prototype.do_many_cycles_unsafe,
        CPU.prototype.do_many_cycles,
    ];
}

This could be put on self["__no_inline_for_closure__"]. This sort of thing can happen in a few other places as well.

Another thing that could be done throughout the code to help with bundlers (vs performance) is to modify code like this:

// Closure Compiler's way of exporting
if(typeof window !== "undefined")
{
    window["CPU"] = CPU;
}
else if(typeof module !== "undefined" && typeof module.exports !== "undefined")
{
    module.exports["CPU"] = CPU;
}
else if(typeof importScripts === "function")
{
    self["CPU"] = CPU;
}

To look like this:

// Closure Compiler's way of exporting
if(typeof module !== "undefined" && typeof module.exports !== "undefined")
{
    module.exports["CPU"] = CPU;
}
else /* window or Worker, put it on the global */
{
    self["CPU"] = CPU;
}

These are just some code-path savings, and won't necessarily help with Worker performance. However, they might help reduce differences between running in window vs. Worker.

humphd avatar Jun 26 '18 19:06 humphd

@humphd I don't really understand the code for V86, so I can't really help on this, but I can't figure out how to compile it to use a web worker, could you explain how to do it? Thanks :)

BelleNottelling avatar Jul 29 '18 03:07 BelleNottelling