Chrome and Opera Optimize for Mozilla-Pioneered Asm.js
blog.mozilla.org
blog.mozilla.org
I was threatened by PNaCl for a while, until I realized that it integrates with Javascript through messaging. I think it could be a really solid complement to the Web platform.
The thing that bothers me about PNaCl is the potential for Chrome to become silo'ed and for Google to start pushing it's own ecosystem over the web, if they can't get other browsers to join in. I don't think they'll actually do that, but the chance is still kind of scary.
Problem is there is history of Google doing exactly this: SPDY.
It's why I will never support any more of these unilateral efforts. Whether something is open or not is irrelevant when in the case of NativeClient every committer works at Google.
No need to wait. ChromeOS and Netflix proves they are already doing this.
And thank god for that. I've never understood the fetish C/++ programmers have for shared memory, and locks, and mutexes. Erlang has a much saner approach to concurrency/parallelism, and web workers isn't terribly far away from Erlang's actor model.
EDIT: That said, I thought about the idea of only allowing typed arrays to be shared, and I actually really like it. I think that's a sane way to approach shared memory in JS, and it could cover some of the use cases that web workers aren't a big help with.
There are some problems which are more amenable to shared mutable memory, especially when performance or memory space is a concern. And for those problems where the sharing of mutable data is not needed, forking, pointer ownership, thread-local data, and const correctness are all old concepts.
No silver bullet.
See, fault tolerance was actually the #1 priority when building Erlang not high concurrency. High concurrency was there too but it was #2. Also the tough part is selling fault tolerance. Only those that have implemented large concurrent systems using shared memory models, plagued by dangling pointers, large mutable state in the middle of everything moving around, and have it fail will appreciate fault tolerance. Most will shrug it off -- "hey look, I can run language shootout's Mandelbrot 10x faster!". There is a trade-off there, of course. Just like in a real OS. If you want to fork separate processes for each request, you'll pay for fault tolerance in performance some, if instead you'd just called a callback in the same process.
(The sender loses access to the buffer after it's sent, so it's still safe)
Experience teaches you that nothing slows down innovation worse than what you propose here...
Yes. That's what killed the vision for massive adoption of desktop Linux for one thing.
That's what hampered a good Java web story (tons of competing frameworks).
It's why there are several slow scripting languages (Python, Ruby, Perl, etc), whereas Javascript got crazy fast as the only game in town when it comes to the web.
The reverse of that (Rails as the "one true framework" instead of tons of competing stuff) is what helped Ruby make waves.
Especially when the "competing platforms/ecosystems" are needlessly competing. It's a waste of effort, people duplicating features and stuff.
>The Central Bureaucracies such as W3C make change (granted positive or negative) slower.
The central bureaucracies are actually "competing platforms/ecosystems" too, only they are competing for inclusion in the one same standard. MS, Apple, Google, Oracle, IBM etc each wanting their own APIs and changes to the final spec (which is slow).
Most progress has been made by ONE SINGLE company going at it and inventing something new on their own that others adopt more or less wholesale (e.g Apple with Canvas, MS with AJAX, Mozilla with asm, etc).
Constrast that to each of those companies having its own competing technology for the same thing (e.g different canvas drawing APIs) instead of adopting one and being done with it.
I am talking about competition on a higher level: e.g. Ruby on Rails vs ASP.NET vs JSP. RoR was not the first one. Do you really think this kind of competition is bad? Was inventing Linux a bad thing because we already had other OS's?
"company going at it and inventing something new on their own" - the very definition of competition: generating something new to get a competitive advantage (new platform, new technology, new framework).
It's true that asm.js wins for compatibility, for obvious reasons. And that's a powerful advantage. And it works in the same runtime that existing web apps do, which likewise a win; Java and especially NaCl have complicated interoperability paradigms. They are not just "a faster web page", which is what 90% of developers really wanted to begin with.
That said, the remaining 10% really do want something more. They want to write targetted architecture-specific assembly, perhaps. They want access to syscall-level abstractions like threads and true sockets (buffer sizes, Nagle settings, timeouts, etc...). And asm.js has nothing for these people.
And despite its simlicity, asm.js is still mostly just a toy. It's got one working compiler backend that isn't packaged sanely anywhere. I've three times now decided to get serious and build emscripten from source, and three times given up -- it lags LLVM releases, it has glitchy behavior. Compare to clang and especially gcc which build robustly and cleanly everywhere and come with elaborate test suites. This isn't a toolchain I'm about to start betting a company on, for sure.
Give it time. I like asm.js too. But it's never going to be The Answer to remotely deployable "native like" code any more than Java was.
Neither PNaCl nor the JVM gives you this.
Are you comparing emscripten to clang? Using clang alone won't get you something you can execute in a web browser — unless you include a CPU emulator in JS.
If in fact you are comparing the asm.js workflow with the PNaCl workflow, they each rely on clang, sure, but PNaCl requires a bigger difference with clang-trunk. It is a plain fork.
> PNaCl is essentially a modified version of Clang. This is done for two reasons. First, it eliminates an install-time dependency. Second, Clang was historically not supported on Windows (but this is beginning to change).
Also, PNaCl has a unique, specific API (Pepper), which is very different from the way emscripten works.
Finally, the comparative workflow to have your app work on the Web.
PNaCl: write HTML/CSS/JS, write manifest, write PNaCl code, compile to pexe, rewrite the code to work with Emscripten, compile to JS via pepper.js.
Emscripten: write HTML/CSS/JS, write native code to work with Emscripten, compile to JS.
Yes, but those 10% are better served by going native. What's the problem in going native using the platform's native SDK?
OH, if you're going to say that native apps don't run in the browser, well, the browser's inherent advantages over native are that (1) it runs everywhere, on every platform and (2) it's based on standards with multiple implementations.
But NaCL for all intents and purposes is native to Chrome and not part of the web (it also doesn't run on ARM chips). NaCL will never be a standard accepted by either Microsoft, or Apple or Mozilla, because it's not portable enough and because it's so freakishly complicated that writing a spec for it is really, really hard and the jury is still out on its technical soundness. And sure, it's open-source, but that's not enough.
So you know, those 10% that want more, can only find comfort in NaCL if they only want to target Chrome's Web Store, which isn't different from targeting an OS. But that's not the open web. For the open web, those 10% have no choice other than Javascript, which is why Asm.js is so awesome, because it exists.
It's fast enough. It's compatible with the existing web. It's platform independent. It runs in any standards-compliant web-browser. That's four wins right there.
It's fundamentally superior. End of discussion.
That said, the remaining 10% really do want something more. They want to write targetted architecture-specific assembly, perhaps.
If they do, they can go do it somewhere which isn't the open web.
When I use a web-browser, me and my devices aren't going to wait for you to fix your webpage to support the architecture I happen to be running. We're going to go somewhere else.
Imagine how impossible it would have been for early Macs and ARM-devices to enter the market if the web was already entrenched in platform-specific Intel x86 code. How many of those websites out there do you think would have been "fixed" in order to work on other platforms, years after the authors abandoned them? I'm guessing a tiny fraction.
They didn't have to though, because the web is cross-platform. This is by design.
We should thoroughly ignore Google's best efforts to reverse this with their proprietary NaCl. Why on earth would we want to change the best quality of the web now that it has already proven its value?
Are you aware that NaCl (the platform-specific version) is only enabled for applications installed through the Chrome Web Store? Chrome will not load NaCl modules from the web. All that is supported for the web is PNaCl, which is platform-independent. See: https://developers.google.com/native-client/dev/nacl-and-pna...
So your hypothetical is not in danger of happening.
That said, that's not what the post I was replying to was suggesting. It was suggesting writing architecture-specific assembly code and putting it on the web. And citing that as a legitimate need which should be addressed by browser-vendors.
Needless to say, as someone who supports an open, cross-platform web, I strongly oppose any such measure.
CSS on the other hand...
So you are factually right, but a lot of people will go and say ah, yes - writing HTML is programming. Which is just untrue.
Or you use pepper.js for compatibility with non-PNaCl browsers, which compiles the PNaCl app to plain JS.
It sounds from the article like Epic announced that Chrome/V8 is fast enough to run the Unreal 3 engine, and Mozilla's trying to spin it as V8 explicitly optimized for a "spec" invented by Mozilla when actually they just made V8 really, really fast.
That said, they do include an asm.js benchmark in Octane 2, so it's clearly on their radar. But as far as I've heard they haven't actually implemented special asm.js typecheckers / AOT compilers like Mozilla has.
As you say, Google included asm.js code in Octane 2, and you can see progress on asm.js benchmarks as Google optimizes in ways that help that style of code on arewefastyet,
http://arewefastyet.com/#machine=11&view=breakdown&suite=asm...
This is also not something new, Google has optimized for asm.js code since the IO keynote much earlier this year where Google reported a 2.4x speedup on an aggregate asm.js benchmark,
http://culturemass.com/2013/05/17/google-io-2013-keynote-par...
There are many ways to optimize for different types of code. Firefox uses the asm.js type system for asm.js, and does AOT compilation, while Chrome chose a different approach. The two approaches have different benefits. But both browsers certainly optimize for asm.js, they both announced doing so and the numbers are proof that they are succeeding.
edit: add link to Octane 2.0 and the asm.js benchmark added there, http://blog.chromium.org/2013/11/announcing-octane-20.html
This press release is a little heavy on spin trying to market asmjs. While it does appear V8 is speeding up asmjs style code, until we know specifically about what they've done in chrome 31/32, this seems mostly like speculation. What if in fact asmjs was causing a degenerate case in their JIT and what they actually did amounted to fixing some bugs?
I don't see how that's any different from optimizing for asm.js. Optimization is often about fixing bugs.
I expect Epic's announcement is more about these glitches being resolved then performance increases. Mozilla's is pure spin.
https://code.google.com/p/v8/source/detail?r=14658 and https://code.google.com/p/v8/source/detail?r=15147
[hint: nothing, they have more to do with how Emscripten has a tendency to produce extremely big functions which no human would write, and JIT has to accomodate for that to hit them in correct moment and not give up on them. Once it hits them however the optimizations that were there for ages, optimizations purely based on JavaScript semantics, start doing what they are intended to do --- make JavaScript run fast]
EDIT: I just ran that demo in Chrome, on the same computer as before and it did improve a lot (getting 50-60 fps in full screen HD), though it still seems smoother in Firefox. Competition is great.
NaCl is not going to make the web x86-dependent. Recognizing the danger of an architecture-specific web, Google has disabled NaCl for everything except the Chrome Web Store. So unless you believe that the Apple App Store has been making the web ARM-specific for the last five years, Native Client is not the x86 lock-in that you may fear.
And in fact, Google now recommends PNaCl over NaCl for this very reason. It recommends NaCl only in certain limited situations: https://developers.google.com/native-client/dev/nacl-and-pna...
And even PNaCl, which requires browser support to run "normally", has a JS fallback called pepper.js. So applications targeting PNaCl do not have a hard dependency on a PNaCl runtime: http://trypepperjs.appspot.com/
[0] Except perhaps plus.google.com? I haven't heard of this before, waiting for more from pcwalton about this.
And plus.google.com. :(
Basically, there is a whitelist of domains in Chrome where NaCl is enabled for non-web-store apps; the basic criteria, according to Google, is that (like the web store) these are places where Google has a lever to move people using NaCl from NaCl to PNaCl over time.
Obviously, this applies to Google's own properties.
That title is making it sound like the changes were aimed at making that one case faster, when they weren't.
And them adding a library to their benchmark doesn't in any way mean that they aim to optimize for it, only that they want to keep a reference on how their code perform. Just because I regularly check how my website renders in IE 6 doesn't mean I'm optimizing for it or that I consider it a target.
No, the changes were certainly aimed at making the case of asm.js code faster. As in the links I posted above, Google has announced they are optimizing for asm.js and that they achieved large speedups on it, they mention it very specifically,
http://culturemass.com/2013/05/17/google-io-2013-keynote-par... http://blog.chromium.org/2013/11/announcing-octane-20.html
> And them adding a library to their benchmark doesn't in any way mean that they aim to optimize for it
No, it exactly means that: Adding it to Google's main benchmark means that they consider it representative of important real-world code, and hence that optimizing for that benchmark means you are optimizing for the right stuff. As the Octane FAQ says,
>> " Octane aims to be representative of actual workloads and execution profiles of real web applications. Octane's goal is to be a proxy for the JavaScript application that you'll encounter when running browser games, highly-interactive web pages or online productivity tools." https://developers.google.com/octane/faq
"use asm";
which signals the asm.js optimizations should be used. Instead, I'd bet the Chrome team are just watching for JS which matches the asm.js spec and optimizing for those cases, like they do for other code paths & structures. That would mean they are optimizing for it, but not supporting it directly.No. All optimizations that V8 are doing are following from the JavaScript specification itself, not from asm.js specification. V8 does not use asm.js specification in any way (including type rules that asm.js prescribes). If you take asm.js code and slightly change typing so that it will no longer pass asm.js type check but still be reasonable V8 will continue to optimize what it can.
Because this is what is happening.
asm.js is as a monolith: "use asm" in the foundation and a pyramid of typing rules, take one out everything crumbles. Right now V8 does not use "use asm" nor relies on any static typing (beyond what can be derived from JavaScript specification).
For example when V8 improves its optimization pipeline to handle coercion of boolean to integer inline this helps asm.js code, but it also helps anyone doing this operation outside of asm.js specification compliant code. This coercion rule is just a part of the language, so I really see this as optimization of JavaScript as whole.
If you specifically make changes to your site in order to make faster on IE6, and it also makes all other browsers fast, the "all other browsers" part is best described as a side-effect.
So did the v8 team do something specially to make asm.js faster? As mraleph said, the answer is no. So the fact that asm.js is now faster in Chrome is side-effect.
The v8 team look at asm.js benchmarks and make changes in v8 to make those benchmarks run faster, that's clear from their announcements. At the same time, those optimizations can also make other code faster, as they try to make them general optimizations as much as possible.
So it's not true it's a "side-effect", since some of the time they literally start the process by looking at asm.js code, and finding how to make it run faster on v8. So asm.js is in a sense directly responsible for the optimization, and asm.js is sped up by it. But at the same time, the optimization added is - unlike Firefox's approach - relatively general, and helps other code too.
In the end, I don't think there is any disagreement between us here.
This is really a philosophical debate at this point. All the one side is saying is that if a team of engineers focuses on making a certain type of code run fast (they look at that code, have benchmarks for it, find stuff that makes it run faster, etc.), then it is fair to say they are "optimizing for that type of code." While the other side is saying that if they write general optimizations that speed up not only that code but other code as well then they are "not optimizing for that type of code."
Both sides are correct in what they mean. The only disagreement is in how to define the term "optimizing for." But as long as we all understand what we mean, there is no disagreement here at all.
Yes, you are exactly correct that v8 does not notice "use asm", but yes, it is also correct that the v8 team has been optimizing for asm.js code, just as they optimize for typescript code (which like asm.js, Google deemed important enough to be put in Octane).
It's compiler itself that is in the Octane (though compiler itself is written in TypeScript). This particular benchmark pressures GC a lot and GC shares the top spot with a load from dictionary stub.
TypeScript is on the different side of the scale compared to asm.js: it produces mostly what a normal human would write. This means normal prototypical inheritance, normal JS objects and so on. There is nothing really special about that. Though of course TypeScript compiler itself have performance profile atypical for a web application or game, it is a compiler after all.
The hottest JavaScript function in this benchmark (if you skip GC and dictionary load) is Scanner.innerScan with 1% ticks. If you look at it you will see a typical scanner function most of compilers have. Any human would write it the same way, actually and the fact that it was written in TypeScript is irrelevant (compiler just stripped type annotations when it was compiling it).
If you sum all this things together you will see why it is incorrect to say "X optimizes for Y" here.
edit: perhaps an even more specific example is the regex stuff in Octane and SunSpider, they test something very narrow. Likewise GC tests that pretty much require a generational GC to be fast, they also test something very specific. While the TypeScript test, as you said, is more general.
Yep. Now look at the list of these things. Do you see what it is in the sum? In the sum it is real-world JavaScript. Which is precisely reveals the goal: JavaScript should run fast.
I think we are looping about this issue because we see different connotations in the sentence "optimize for asm.js". I see connotation "optimize for asm.js as described by it's specification (with AOT and stuff)", while what actually happens is that underlying JavaScript that serves as foundation for asm.js specification is being optimized. That is why I always prefer to say "asm.js-style code".
> Likewise GC tests that pretty much require a generational GC to be fast
Actually with Splay it is easier to be fast if you don't have a moving generational GC :-)
I didn't mean splay necessarily ;) It is easy to make a benchmark that relies heavily on GGC or escape analysis.
I would say I am more OK with it as it highlights the fact that it's about spirit not about complete adherence to asm.js spec.
Unfortunately there is no compact and at the same time clear way to say what V8 does right now, e.g. saying "optimizing for type stable code" is most accurate but does not help to understand what V8 actually does and how it relates to improvements on Emscripten output.
You still optimized for IE6. It just so happened that your optimizations made your site faster in other browsers too.
In what bizarro world?
>only that they want to keep a reference on how their code perform
That's the very definition of optimization (and avoiding regressions).
Which means that Chrome will now optimize for bitwise computing without holding any bias for or against asm.js. Asmjs developers can claim the mantle of bitwise computing and anybody who uses bitwise computing or optimizes for bitwise computing is really endorsing asm.js
In the end, some hugely popular cross compiled games will drive adoption of both technologies to the point where they are ubiquitous and supported by all major vendors. Apple doesnt want people saying "Wah look at how poorly Safari handles that game compared to Chrome/Firefox".
[1] http://games.greggman.com/game/thoughts-on-asm-js-vs-pnacl/#...
I don't see NaCl as a viable alternative, I see it as an attempt of locking down the user to a specific browser, and also as a potential security worry.
And, for me personally if I'm going to run a native app, I see no reason at all to have it run inside a web browser.
This is never going to happen. JavaScript is far too entrenched.
Comparing the current stable Chrome 31.0.1650.57 and Firefox 25.0.1 on my Windows box running at 1920x1200 yields 57.8 fps for Chrome and 81.7 fps for Firefox. Note that Firefox is pegged at a maximum of 60fps by default which will affect benchmarks. You can disable that limit with the information in the FAQ.