开发者

What tricks did Fabrice Bellard use to make his PC emulator in Javascript so fast?

Fabrice Bellard's PC emulator implemented in J开发者_如何学Cavascript is impressively fast--it boots a small Linux image in the browser within a few seconds.

What techniques were used to get this performance?


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.


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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜