asm.js

From Infogalactic: the planetary knowledge core
Jump to: navigation, search
asm.js
Designed by Mozilla
First appeared 21 March 2013; 11 years ago (2013-03-21)[1]
OS Platform independent
Website asmjs.org
Influenced by
JavaScript

asm.js is an intermediate programming language designed to allow computer software written in languages such as C to be run as web applications while maintaining performance characteristics considerably better than standard JavaScript, the typical language used for such applications.

asm.js consists of a strict subset of JavaScript, into which code written in statically-typed languages with manual memory management (such as C) is translated by a source-to-source compiler such as Emscripten (based on LLVM).[2] Performance is improved by limiting language features to those amenable to ahead-of-time optimization and other performance improvements.

Mozilla Firefox was the first web browser to implement asm.js-specific optimizations, starting with Firefox 22.[3]

Design

asm.js consists of a strict subset of the JavaScript language. It enables significant performance improvements for web applications that are written in statically-typed languages with manual memory management (such as C) and then translated to JavaScript by a source-to-source compiler. Asm.js does not aim to improve the performance of hand-written JavaScript code, nor does it enable anything other than enhanced performance.

It is intended to have performance characteristics closer to that of native code than standard JavaScript by limiting language features to those amenable to ahead-of-time optimization and other performance improvements.[4] By using a subset of JavaScript, asm.js is largely supported by all major web browsers,[5] unlike alternative approaches such as Google Native Client.

Code generation

Lua error in package.lua at line 80: module 'strict' not found.

asm.js is not typically written directly: instead, as an intermediate language, it is generated through the use of a compiler that takes source code in a language such as C++ and outputs asm.js.

For example, given the following C code:

int f(int i) {
  return i + 1;
}

Emscripten would output the following JS code:

function f(i) {
  i = i|0;
  return (i + 1)|0;
}

Note the addition of |0 and the lack of type specifiers. In JavaScript, bitwise operators convert their operands to 32-bit signed integers and give integer results. This means that a bitwise OR with zero, an otherwise useless operation, converts a value to an integer. By doing this for each parameter, this ensures that if the function is called from outside code, the value will be converted to the correct type. This is also used on the return value, in this case to ensure that the result of adding 1 to i will be an integer (as otherwise it could become too large), and to mark the return type of the function. These conversions are required by asm.js, so that an optimising compiler can produce highly efficient native code ahead-of-time. In such an optimising compiler, no conversions are performed when asm.js code calls other asm.js code, as the required type specifiers mean it is guaranteed that values will already have the correct type. Furthermore, rather than performing a floating-point addition and converting to an integer, it can simply do a native integer operation. Together, this leads to significant performance benefits.

Here is another example to calculate the length of a string:

size_t strlen(char *ptr) {
  char *curr = ptr;
  while (*curr != 0) {
    curr++;
  }
  return (curr − ptr);
}

This would result in the following asm.js code:

function strlen(ptr) { // calculate length of C string
  ptr = ptr|0;
  var curr = 0;
  curr = ptr;
  while (MEM8[curr]|0 != 0) {
    curr = (curr + 1)|0;
  }
  return (curr − ptr)|0;
}

In the generated code, the variable MEM8 is actually a byte-by-byte "view" of a typed buffer, which serves as the "heap" of the asm.js code.

Performance

Since asm.js runs in a browser, the performance heavily depends on both the browser and hardware. Preliminary benchmarks of C programs compiled to asm.js are usually within a factor of 2 slowdown over native compilation with Clang.[6]

Much of this performance gain over normal JavaScript is due to 100% type consistency and virtually no garbage collection (memory is manually managed in a large typed array). This simpler model with no dynamic behavior, no memory allocation or deallocation, just a narrow set of well-defined integer and floating point operations enables much greater performance and potential for optimization.[citation needed]

Mozilla's benchmark from December 2013 showed significant improvements: "Firefox with float32 optimizations can run all those benchmarks at around 1.5× slower than native, or better."[7] Mozilla points out that the performance of natively compiled code is not a single measure but rather a range, with different native compilers (in this case Clang and GCC) delivering code of differing performance. "In fact, on some benchmarks, like Box2D, FASTA and copy, asm.js is as close or closer to Clang than Clang is to GCC. In one case, asm.js even beats Clang by a slight amount on Box2D."[7]

Implementations

The Emscripten project provides tools that can be used to compile C and C++ codebases (or any other languages that can be converted to LLVM) into asm.js.[2]

All browsers with support for the newest edition of JavaScript should be able to run asm.js code, as it is a subset of that specification. However, since features were added in that edition to enable full asm.js support, older browsers lacking those features may encounter problems.

Some browser implementations are especially optimised for asm.js:

  • Mozilla Firefox was the first web browser to implement asm.js-specific optimizations, starting with Firefox 22.[3] OdinMonkey, Mozilla's asm.js ahead-of-time compiler used in Firefox, is a component of IonMonkey, the JIT compiler of SpiderMonkey.
  • Microsoft is implementing support for asm.js in Chakra, the JavaScript engine used by Microsoft Edge, performing validation to produce highly optimised JIT code.[8]
  • The optimizations of Google Chrome's V8 JavaScript engine in Chrome 28 made asm.js benchmarks more than twice as fast as prior versions of Chrome,[9] although Chrome's V8 does not use ahead-of-time compilation.

Adoption

Lua error in package.lua at line 80: module 'strict' not found.

Almost all of the current applications based on asm.js are C/C++ applications compiled to asm.js using Emscripten or Mandreel. With that in mind, the kind of applications that are going to target asm.js in the near future are those that will benefit from the portability of running in a browser but which have a level of complexity for which a direct port to JavaScript would be infeasible.

So far, a number of programming languages, application frameworks, programs, libraries, games, game engines and other software have already been ported.[10] Some of them are given below.

Programming languages

Application frameworks

  • pepper.js: Ports of miscellaneous PNaCl apps (earth, voronoi, bullet, etc.)[15]
  • Qt: ports of various Qt demos, plus KDE apps, such as Kate[16]

Programs and libraries

Game engines

Games

Emulators

  • Dosbox[35]
  • Start9.io: a web emulation platform targeting multiple gaming architectures
  • JSMESS: a port of the MESS emulator for many game consoles and computer systems[36]

Mathematics

  • HTML5 Fractal Playground[37] – draws iterating-function generated fractals, such as the Mandelbrot fractal.

See also

References

  1. Lua error in package.lua at line 80: module 'strict' not found.
  2. 2.0 2.1 Lua error in package.lua at line 80: module 'strict' not found.
  3. 3.0 3.1 Lua error in package.lua at line 80: module 'strict' not found.
  4. Lua error in package.lua at line 80: module 'strict' not found.
  5. Lua error in package.lua at line 80: module 'strict' not found.
  6. Lua error in package.lua at line 80: module 'strict' not found.
  7. 7.0 7.1 Lua error in package.lua at line 80: module 'strict' not found.
  8. Lua error in package.lua at line 80: module 'strict' not found.
  9. Lua error in package.lua at line 80: module 'strict' not found.
  10. Lua error in package.lua at line 80: module 'strict' not found.
  11. Lua error in package.lua at line 80: module 'strict' not found.
  12. Lua error in package.lua at line 80: module 'strict' not found.
  13. Lua error in package.lua at line 80: module 'strict' not found.
  14. Lua error in package.lua at line 80: module 'strict' not found.
  15. Lua error in package.lua at line 80: module 'strict' not found.
  16. Lua error in package.lua at line 80: module 'strict' not found.
  17. Lua error in package.lua at line 80: module 'strict' not found.
  18. Lua error in package.lua at line 80: module 'strict' not found.
  19. Lua error in package.lua at line 80: module 'strict' not found.
  20. Lua error in package.lua at line 80: module 'strict' not found.
  21. Lua error in package.lua at line 80: module 'strict' not found.
  22. Lua error in package.lua at line 80: module 'strict' not found.
  23. Lua error in package.lua at line 80: module 'strict' not found.
  24. Lua error in package.lua at line 80: module 'strict' not found.
  25. Lua error in package.lua at line 80: module 'strict' not found.
  26. Lua error in package.lua at line 80: module 'strict' not found.
  27. Lua error in package.lua at line 80: module 'strict' not found.
  28. Lua error in package.lua at line 80: module 'strict' not found.
  29. Lua error in package.lua at line 80: module 'strict' not found.
  30. Lua error in package.lua at line 80: module 'strict' not found.
  31. Lua error in package.lua at line 80: module 'strict' not found.
  32. Lua error in package.lua at line 80: module 'strict' not found.
  33. Lua error in package.lua at line 80: module 'strict' not found.
  34. Lua error in package.lua at line 80: module 'strict' not found.
  35. Lua error in package.lua at line 80: module 'strict' not found.
  36. Lua error in package.lua at line 80: module 'strict' not found.
  37. Lua error in package.lua at line 80: module 'strict' not found.

External links