
Gap between asm.js and native gets narrower with float32 optimizations - evilpie
https://hacks.mozilla.org/2013/12/gap-between-asm-js-and-native-performance-gets-even-narrower-with-float32-optimizations/
======
AndrewDucker
The original blog post is well worth reading:

[https://hacks.mozilla.org/2013/12/gap-between-asm-js-and-
nat...](https://hacks.mozilla.org/2013/12/gap-between-asm-js-and-native-
performance-gets-even-narrower-with-float32-optimizations/)

------
arturadib
Oh look another JS vs native benchmark...

I still think we're missing the point; we're focusing on the wrong benchmarks.
We're putting too much emphasis on JS speed, when in reality most web apps are
behind native because of lack of (perceived) graphics performance.

The shortcut out of this requires a greater variety of GPU-accelerated CSS
transitions/DOM changes, as well as easier computations and DOM manipulations
off the main thread, which cause horribly noticeable UI hiccups. Web Workers
are still too primitive (e.g. no DOM access whatsoever) and slow (e.g. no
shared memory).

Not saying it's unimportant to improve JS's CPU performance; just saying that
we're focusing too much on the wrong battle in the war against native.

~~~
SigmundA
WebGL anyone? This is what does most of the heavy lifting in the main asm.js
use case: games.

I am still waiting to see a UI framework built using asm.js and WebGL. Maybe
even a existing native framework ported over, something like WPFe(Silverlight)
might be about as difficult as a game engine to port.

Asm.js still has no solution to shared memory threads, which will be an issue
for any modern game engine I would imagine.

~~~
mistercow
>Asm.js still has no solution to shared memory threads, which will be an issue
for any modern game engine I would imagine.

This feels to me like the elephant in the room, not just for asm.js, but for
JS in general. We have Web Workers, and that _sounds_ like a solution, so it
dampened the discussion of parallelism on the web. But in a _lot_ of
situations, Web Workers just don't cut it. Copying memory back and forth is
just too inefficient.

~~~
SigmundA
I agree, I can appreciate the idea of share nothing threading(web workers)
which is more like multi-process rather than multi-threading, it's probably
the better model for much of the threading use cases out there. However there
are performance critical scenarios where lightweight shared memory threads
will always win and will be required if it is to be a valid compile target for
c/c++ coded bases.

~~~
nitrogen
If there's a way to do zero-copy message passing in web workers (or
equivalently, overhead-free transfer of object ownership between threads),
shared memory may be unnecessary.

~~~
gmac
This is available in recent versions of Chrome and Firefox, on the form of
Transferable objects: [https://developer.mozilla.org/en-
US/docs/Web/API/Transferabl...](https://developer.mozilla.org/en-
US/docs/Web/API/Transferable)

~~~
mistercow
That helps, but it still means you can only have the data on one thread at a
time. What would be a _massive_ help would be if you could split a buffer into
non-overlapping views, and transfer each view to a separate worker. Some
algorithms would still be challenging or impossible to implement this way,
like parallel prefix sum algorithms, but it would still greatly widen the
number of things you could do in parallel.

------
cpprototypes
Some thoughts/questions about asm.js

1) I understand the C/C++ -> LLVM -> Emscripten -> asm.js process. But I heard
they're also working on supporting GC languages (like Java and Go). How would
this work exactly? Wouldn't they first have to port the entire JVM or Go
runtime into asm.js? And every time a Java/Go -> asm.js program is downloaded,
it would basically also download the entire JVM/Go runtime as well?

2) Would it be possible to use GUI frameworks (like Qt for C++ and maybe Swing
for Java in the future) to build GUIs and directly output to canvas?

~~~
camus2
Qt running in the browser :

[http://badassjs.com/post/43158184752/qt-gui-toolkit-
ported-t...](http://badassjs.com/post/43158184752/qt-gui-toolkit-ported-to-
javascript-via-emscripten)

JVM running in the browser :

[http://plasma-umass.github.io/doppio/about.html](http://plasma-
umass.github.io/doppio/about.html)

Anything is possible in the browser.

~~~
serge2k
Anything is possible in brainfuck too. You can also do all your coding in just
C++ templates.

Doesn't make it a good idea.

~~~
coldtea
Yes, if only using the browser as a platform also had other benefits... Oh,
wait!

~~~
serge2k
I fail to see the benefit of building a jvm to run in a javascript engine.

I would rather see effort to develop a better language than JS for the web.
Now someone will bring up emscripten and dart...

~~~
coldtea
> _I fail to see the benefit of building a jvm to run in a javascript engine._

That's because you picked a very specific example to suit your argument.

How about seing the benefit of building games to run in the browser with near
native speed? Or something like Mathematica? Or an image editor, etc etc...

------
gizmo
The article doesn't have much depth, unfortunately. I like asm.js but I'm
still hoping for Dart support in Firefox and other modern browsers.

~~~
eonil
AFAIK, Dart can run on bare JS without any extra support.

~~~
kevingadd
Dart2js does not currently implement the whole language. Integer/float
semantics and support for large integers don't work (it seems like they didn't
implement them manually, so it just falls back to doubles?), and there are
probably other things I don't know about missing.

I should point out that emscripten and many other JS-targeting compilers (like
JSIL) emulate int64 semantics directly so that apps using them _do_ work. It's
kind of strange for the Dart team to have not gotten this right yet when Dart
is at 1.0.

~~~
pcwalton
> Integer/float semantics and support for large integers don't work (it seems
> like they didn't implement them manually, so it just falls back to
> doubles?), and there are probably other things I don't know about missing.

That's going to be really unfortunate if pages start relying on the proper
behavior and become Chrome-only as a result...

~~~
floitsch
That's not really the problem. Web developers have learned from the past and
don't just build web-pages for one browser only. On the contrary... Developers
now sometimes need to support outdated browsers with little market share (IE8
for example), instead of actively pushing the users to upgrade.

The discrepancy between Dart and JS numbers is mostly an issue for the
developers. When they deal with numbers in specific ranges, they need to run
dart2js more frequently (to test if their code works) instead of relying on
Dartium (and its F5 development cycle).

After 2 years of Dart development, numbers have rarely been an issue in
practice. Developers know when they deal with numbers > 32/53bits and work
around it.

~~~
BrendanEich
Web developers know too well the trap of testing only on one browser, which
when Dart comes to Chrome, will be Chrome. Testing all input data in a space
that exceeds the integral domain of double is hard. Murphy says there will be
bugs in other browsers when one's app tests "work in Chrome".

For a wannabe-cross-browser, wannabe-standard (Ecma has a sorry history of
proprietary standards: C#, OOXML) language pushed by a super-rich big company
with what? 60 or more engineers on the project, optics must matter. Why not
fix the bignum-not-emulated-in-JS bug? It's easy, GWT has BigInteger emulation
code in JS lying around the Googleplex. Just plug that in if the code needs
it.

The obvious risk remains what I cited in HN two years ago: Google letting
dart2js be sub-standard, using all its strength and leverage to promote Dart
in combination with DartVM, letting users of other browsers "blame their
browser" when things don't quite work as well as in Chrome.

Given market share among browsers currently, I think this will backfire, but
it could inflict collateral damage too -- on developers as well as on users.
And it just plain looks bad. People expect better of Google, and they ought
to.

/be

~~~
spankalee
You must realize how different the situations are between Java BigIntegers and
Dart integers.

~~~
BrendanEich
Please, inform me, if you are not trolling on the cheap.

[https://www.dartlang.org/articles/numeric-
computation/](https://www.dartlang.org/articles/numeric-computation/)

[http://docs.oracle.com/javase/7/docs/api/java/math/BigIntege...](http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html)

Both arbitrary precision immutable integer types. If some corner case differs,
my point stands. Google has more than enough engineers on Dart to do the work
of writing a bignum library in JS, if they can't find one to use that someone
already wrote.

/be

~~~
spankalee
I'm definitely not trolling. I truly thought you would understand the basic
difference.

Big integer support in Dart is not an issue of writing a bignum library.
That's already been done. The difficulty is in supporting the single integer
type in a way that's performant for numbers < 2^53

Java has fixed width ints, Dart has infinite precision ints. In Java when
dealing with ints, you're always in the int domain, and when dealing with
BigIntegers you're always in the BigInteger domain. In Java operations on ints
can overflow. In Dart operations on ints don't overflow - internally, if the
result doesn't fit in an machine int a bigint is returned.

In JavaScript you have a few choices when implementing infinite precision
ints: 1) Use a single bigint type for all ints, which will be incredibly slow.
2) Use two types for ints, the built-in number and a BigInteger class. This
means a lot of expensive type and overflow checks that slow down basic numeric
operations. 3) Don't implement infinite precision ints.

Compile-to-JS languages can use static analysis to do better. dart2js already
uses type inferencing extensively to eliminate type checks where it can, but
eliminating the checks for ints would require range propagation which is much
trickier, and doesn't work in a lot of cases.

~~~
BrendanEich
"I truly thought" you would not raise a question to which V8/Dart people
already know the answer. Range prop is not the only solution.

Use JIT techniques to speculate profitably that most ints fit in JS doubles.
This can be done in JS-hosted VMs, just as in machine-code-generating native
VMs.

Again, this is extremely old hat to the Dart/V8 folks. See, e.g.

[http://mraleph.tumblr.com/post/24351748336/explaining-js-
vm-...](http://mraleph.tumblr.com/post/24351748336/explaining-js-vm-in-js)

In SpiderMonkey, we augment JIT techniques with online type inference that
distinguishes int from double. The same type inference could add bignum to the
speculative tower. See

[http://rfrn.org/~shu/drafts/ti.pdf‎](http://rfrn.org/~shu/drafts/ti.pdf‎)

This avoids most of those checks that you _assume_ are too expensive (and by
assuming, so casually fork Dart semantics).

Here is a JS version of [Hackett&Shu, PLDI 2012], from @pcwalton:

[https://github.com/pcwalton/doctorjsmm/](https://github.com/pcwalton/doctorjsmm/)

Can the full JIT+TI approach to bignum/double/int perform well enough for
dart2js? Better find out, because forking semantics is just the wrong thing.

Another road not taken: we hear "can't wait for JS to get better", but Dart
started at least by 2010, possibly earlier.

[http://wiki.ecmascript.org/doku.php?id=strawman:bignums](http://wiki.ecmascript.org/doku.php?id=strawman:bignums)

could have been proposed and actually worked into ES6 by now, but the Dart
team was in stealth mode (Dash) for too long. Still, better late than never.
There's time for ES7. Who from Google will actually do the work in V8 and with
Ecma TC39?

/be

~~~
spankalee
This is sounding less and less like just plugging GWTs BigInteger
implementation into Dart, which is exactly my point when I said you must know
the difference.

~~~
kevingadd
Using a GWT BigInteger for all dart2js integers would work just fine and
provide correct semantics, but if it doesn't meet their performance bar,
that's a failure of design - not an excuse for cutting corners and shipping a
dart2js that produces wrong behavior.

This could have been accounted for with a better language design, but it
wasn't.

~~~
BrendanEich
Could have been accounted for in language design, dart2js effort, bignums-for-
JS effort, or some combination of the last two. I don't want to assume a
conclusion, but the lack of a fix for
[http://code.google.com/p/dart/issues/detail?id=1533](http://code.google.com/p/dart/issues/detail?id=1533)
is a problem, even if there's no immediate fix. It is fixable.

/be

------
daigoba66
I wouldn't say asm.js is a spin-off. In fact it's a strict subset of
JavaScript, though designed to be used as a compiler target rather than
directly coded. The web browser can then execute the code in a highly
optimized (hopefully, eventually near native performance) fashion.

Brendan Eich talks a lot about this in a recent presentation:
[http://www.infoq.com/presentations/web-evolution-
trends](http://www.infoq.com/presentations/web-evolution-trends)

~~~
johnbm
How is it a strict subset when they already added Math.imul and now
Math.fround?

~~~
pcwalton
Math.imul and Math.fround are in the ES6 draft, which has consensus and cross-
vendor support:
[https://people.mozilla.org/~jorendorff/es6-draft.html](https://people.mozilla.org/~jorendorff/es6-draft.html)

~~~
johnbm
As in, not in IE 11?

~~~
pcwalton
I see no indications that IE will not implement ES6, as they're on the
committee and participating.

------
Herald_MJ
Are we calling asm.js a "spin-off" now?

~~~
azakai
Yes, "spin-off" is not a good description. But I guess the article wanted to
make things less technical in the title.

------
zurn
The reason this improves performance is documented at
[https://blog.mozilla.org/javascript/2013/11/07/efficient-
flo...](https://blog.mozilla.org/javascript/2013/11/07/efficient-
float32-arithmetic-in-javascript/) \- float32 typed arrays and more efficient
emulation of C++ float32 arithmetic seem to be the main things.

------
alok-g
Could someone please explain me where mankind is going currently in software
development:

Here is my current understanding (approximated heavily to allow seeing the big
picture) and presented in non-linear chronological order:

== Note: I am genuinely trying to construct the big picture. Please help me
understand and not offer just plain criticism that does not teach me. ==

1\. There were multiple processors and operating systems. Programming
languages like C created with the idea of writing programs once and just
compiling for different platforms. But alas, systems were still too different
to handle with a common code base. Many languages like C++ came along, but do
not provide cross-platform libraries for many things like GUI development.
Third parties libraries did, but native UI/UX not achieved still?

2\. Java created with the idea of writing programs once (and even compiling to
the byte code once) and running everywhere, thus solving compatibility issues
C and C++ had across platforms. But alas, writing once and running everywhere
were still too different in a common code base (Is this true?), especially
with mobile devices coming along that bring different UI/UX requirements. Also
native UI/UX was not achievable (Is this true?).

In the meanwhile:

A. Installation of software on the local machine (aka caching it locally) and
constantly updating it was a pain. Automatic updates popularly used but
unpatched machines still exist.

B. Browsers came along with static pages, then gradually added more and more
interactivity.

C. Machines and networks became fast enough to install the software live from
a website when a user visits and remove it when the browser cache is cleared.

So now:

3\. Applications start getting developed in Javascript (and other
technologies) inside a browser. Native UI/UX still performs better on mobile
(and on desktops too in my experience). Browsers still struggle somewhat with
standardization.

4\. The legacy code from #1 above is now being connected to #3 above allowing
even operating systems and VMs to run inside the browser.

So now we may have C++ code (originally designed to compile natively) now
converted to Javascript running inside a browser, that interprets/JIT's that
Javascript to run natively on the machine/OS, where the browser itself is
written in C++ or so, runs as a visible or hidden layer on the top of the OS
or VM, which by itself is written on C++ or so, and finally runs on the
processor on which the original C++ code was designed to run on.

While I certainly appreciate the flexibility of flows this offers, I am still
trying to make sense of all this from the progress made by mankind as a whole.
What is the ultimate problem that we are trying to solve? Compatibility
between platforms and uniformity of experience across them? Improvements made
to the software development processes (better languages)? Loading programs
securely into the local machine (caching) instead of installing?

No matter which direction I think, it seems to me that if mankind were to
think these through, and were not to have the purely historical elements in
the picture, the problems we have should "technically" have been solvable more
easily than the path mankind has taken.

Again, I am seeking help and inputs to understand this better, not
underestimating the value of efforts made by people around the world, or
criticize any such effort including asm.js.

~~~
yetanotherphd
I think your comment would be clearer if you could answer the question "what
would seem to be a better alternative?".

Google's PNaCl is more elegant since it doesn't involve js-that-is-also-
bytecode but it accomplishes essentially the same task.

Creating a new cross-platform UI framework would be essentially recreating
HTML5 anyway, so I don't think there would be a big advantage there.

~~~
nitrogen
A cross-platform UI framework would look almost nothing like HTML5. The
document model is a significant hindrance to widget-based UI design that is
just barely beginning to be worked around with new CSS and HTML features that
still lack browser support.

UI design benefits from a completely different structure than text-oriented
documents -- layout managers, containers, spacers, grids, reusable components,
nearly all missing from current browsers.

~~~
jnbiche
>UI design benefits from a completely different structure than text-oriented
documents -- layout managers, containers, spacers, grids, reusable components,
nearly all missing from current browsers.

Oh, but it's coming soon, via both JavaScript and Dart:

[http://www.polymer-project.org/](http://www.polymer-project.org/)
[https://www.dartlang.org/polymer-dart/](https://www.dartlang.org/polymer-
dart/)

~~~
pessimizer
Reimplemented 20 years after they were common on every platform.

~~~
scotth
so?

~~~
nitrogen
So it demonstrates how much more difficult UI design is using HTML5 versus
every other UI design option out there. It's often worth it for the platform
independence, but we could've done _much_ better if we designed a UI markup
format from scratch.

------
ilaksh
Throwing away all of the advantages of dynamic scripting is not the answer. We
just need better webgl support in browsers.

~~~
lmm
What advantages would those be? Do they still apply when compared to a modern
strongly-typed language with type inference and typeclass-like functionality,
like Scala?

~~~
millstone
The big advantage of dynamic typing is that your code only needs to be correct
on the code paths that are actually taken. That's important for the web, which
is full of browser specific hacks, polyfills, feature detection, etc.

Consider the difficulty of doing static type checking for a property like
window.localStorage. Its type depends on the runtime environment, and may not
exist at all. So static type checking against one browser environment doesn't
give you much assurance that your code will type check in other browsers. You
really do need to do type checking at runtime.

~~~
EpicEng
Yeah that's what polymorphism is for. window.localStorage would just be the
interface, the underlying concrete type is irrelevant.

~~~
millstone
window.localStorage doesn't exist in (for example) IE 7, and it may or may not
exist in IE8 depending on the domain. So you can't rely on the interface being
the same.

~~~
EpicEng
Plenty of libraries written in statically typed languages add features which
may not be supported on legacy platforms. There are ways to deal with this. In
version X you provide a way to let the client know that function Y is not
supported on the current platform.

It's not like the web is some completely different animal, it's just an
example of poor/little standardization and a design which has not evolved well
over time.

~~~
millstone
My point was not that static typing makes this stuff impossible, just more
awkward and difficult.

------
jorgecastillo
If you disagree with the following opinion please don't down vote me instead
enlighten me.

Frankly I don't see the point of compiling C/C++ to JavaScript. If you'r using
C/C++ you might as well compile to machine code, it's not like you gain
anything by compiling to JavaScript.

~~~
jamesjporter
What tom said; also typing a url in a browser is a lot easier than installing
something. This might sound silly but for the typical computer user (and even
many nerds!) it makes a big difference.

------
clavalle
*for very specific types of applications.

