8

Fabrice Bellard's PC emulator implemented in Javascript is impressively fast--it boots a small Linux image in the browser within a few seconds.

What techniques were used to get this performance?

nibot
  • 14,428
  • 8
  • 54
  • 58
  • 1
    One reason are [typed arrays](http://www.khronos.org/registry/typedarray/specs/latest/) I guess, as written here: *The code is written in pure Javascript using the W3C Typed Arrays. A slightly slower fallback mode is implemented for browsers missing this support.* – Felix Kling Jun 05 '11 at 19:22
  • @Felix Kling - It boots linux (and compiles the example program) quite fast even in IE9, which I don't think has typed arrays (not sure about that). – Daniel Earwicker Jun 05 '11 at 19:27
  • @Daniel: I'm not saying that this is the *only* reason ;) I don't know about IE9... – Felix Kling Jun 05 '11 at 19:29
  • Yeah, I'm just raving about how cool it is! I used to explain to people how generally powerful JS is by saying "You could write a VM in it, in principle - it could run Linux, or whatever! Obviously in practice it would be ridiculously slow..." But I've owned real PCs that boot linux slower that this. So I need a new example. I and some colleagues were just laughing in astonishment at it when we first saw it. I assumed it was a cheap hoax until I'd dug into it a bit. – Daniel Earwicker Jun 05 '11 at 19:33
  • Woops, this is a dupe of http://stackoverflow.com/questions/6030407/how-does-linux-emulator-in-javascript-by-fabrice-bellard-work – nibot Jun 06 '11 at 13:00

4 Answers4

5

I used the excellent http://jsbeautifier.org/ to prettify the minified JS code. It looks to me like painstakingly written, un-fussy, sensible procedural code. It's a magnificent achievement in itself, but the credit has to be shared with the phenomenal performance of modern JavaScript interpreters.

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
5

I believe that sharing some general credit with "speed" of the modern JS interpreter is a far way an offtopic in the list of Bellard's techniques (since he does not replace browser's engine). What are his optimization techniques? is a great question and I would like to get a more detailed record on it.

The points I can name so far

  1. (Optional) JS Typed arrays exclude unnecessary memory allocation dynamics (resizing). Fixed type (size) allows to allocate contiguous blocks of memory (with no variable-length elements' segments in such blocks) and uniformly address elements of a single type.
  2. Fast boot by a custom minimalistic booter (see linuxstart code published by Fabrice, also see his project called TCCBOOT http://bellard.org/tcc/tccboot.html)
  3. Optimized uncompressed embedded kernel (See the kernel configuration, it is extra tiny and optimized for small "linuxes").
  4. Minimal number of devices (Devices are super standard and easy to recognize by the kernel. So far, I have properly studied serial device but the rest benefits from similar properties). Ramdisk initialization is rather slow though.
  5. Small (2048 blocks) uncompressed root.bin ext2 system. The root system consists of minimal combination (rootfs, proc, tmpfs, devpts). No swap.
  6. (Unsure) he has patched the buffer size for ttyS0 (serial port device, or actually the kernel UART driver - to be precise) which communicates to terminal. Communication is in any way buffered using his term.js binding (I have found no transmit buffer in UART itself). Note that emulation (as in this case) can be much faster than the real thing.

Please also mind the browser cache while refreshing the page. It kicks very fast if its all in memory (optimized by the host OS). Performing direct (if cached - in-memory) copying (with load_binary()) of "uncompressed" binary segments (start_linux.bin, vmlinux26.bin, root.bin). No hard disk I/O limitations.

Yauhen Yakimovich
  • 13,635
  • 8
  • 60
  • 67
2

As of 2018, Fabrice has used asm.js and WebAssembly to achieve this.

You can read more here.

If you look at the Inspector (or we know as Chrome DevTools, or Firefox's Inspector), you would see some wasm:// sources (on Firefox), implying that he used WebAssembly to achieve this.

-2

Maybe using a C to JavaScript compiler? Like Emscripten: http://code.google.com/p/emscripten/

Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
  • 2
    That shouldn't speed up *JavaScript* at all. – Marcel Korpel Jun 05 '11 at 20:43
  • 1
    But it generates *optimized* JavaSript code (mimic optimized instructions). – Diego Sevilla Jun 05 '11 at 21:40
  • You can do that in JavaScript yourself. Moreover, it remains JavaScript, that has to be interpreted/semi-compiled by a JavaScript engine. And [its FAQ states](https://github.com/kripken/emscripten/wiki/FAQ): “Right now generated code is 10x slower than gcc -O3 - which is not great, but not that bad either. This will get better with improvements in LLVM, JavaScript optimizers like the Closure Compiler, and JavaScript engines themselves”. And to add: several techniques are totally different in JavaScript, so those will have to be mimicked. – Marcel Korpel Jun 06 '11 at 12:07
  • 1
    Ironically, as of 2021, Fabrice's JSLinux actually does use emscripten (he built TinyEMU, the underlying emulation engine, by hand and used emscripten to convert ti to Javascript! https://bellard.org/jslinux/tech.html) – Akshat Mahajan Apr 26 '21 at 03:46