Google launches Portable Native Client
thenextweb.com
thenextweb.com
I often think of software as "walking a path." What I mean by this is that there are often different approaches to the same problem, and these start out as just basic, undeveloped ideas. But put smart people on it (and I have high regard for both the Google and Mozilla engineers on these projects) and let them refine these ideas over time and you'll learn more about all of the consequences, the fundamental strengths and limitations, of these approaches.
I first had this thought when working at Amazon. I remember hearing an off-hand comment about how S3 and Dynamo, both Amazon projects that started around the same time, started with very different consistency goals (Dynamo: very weak, S3: very strong) but as the details were fleshed out, ended up coming towards each other and both became more moderate.
I think that's extremely valuable knowledge, because it can become part of the body of resources that any future designer can look at. Whenever you have an idea, chances are other people have "walked the path" of that idea (or some variant of it) before, and reading about their experience can help you see down the road and anticipate what practical problems you'll run up against. You might have an idea for how to improve on what the previous designers did, but by reading about their experience you can save yourself a lot of the work they already did.
For this reason, I look extremely forward to watching these two projects evolve and compete, and in doing so, to learn more about the fundamental properties/tradeoffs of this design space.
That also means it's effectively encouraging asm.js adoption, which might give Apple and Microsoft enough of a kick to optimize that. Google seem to already be planning on it (they added some asm.js tests to their Octane benchmark).
It also might be useful if, at some point, other browsers want to implement a PNaCl runtime. One of the main sticking points (aside from the use of LLVM bitcode, which is not something LLVM was designed for) was that it requires the Pepper API, which is huge, and duplicates much of the existing web APIs. Google have the spare engineers to do that, but Mozilla certainly doesn't.
A reverse of that would be useful too - an implementation of the standard web APIs on top of Pepper, so you could re-target an asm.js app to PNaCl. Or some kind of tooling that lets you transparently target both.
Maybe we'll see some kind of convergence thing going on? Wouldn't surprise me too much if they started evolving slightly towards one another. I think it's probable that asm.js will eventually get some kind of compact bytecode representation, especially if it can be implemented as a shim to allow it to load in existing browsers.
I'd prefer the inverse of pepper.js and deprecation of Pepper. Way back in the plugin-futures days, every other browser vendor rejected Pepper because it duplicated Web APIs and a C binding to the Web APIs would be more useful. To me, Emscripten and pepper.js just shows that this was true. Emscripten provides C bindings to Web APIs, and pepper.js shows that Pepper is effectively equivalent to the functionality the Web APIs provide. So I see no need for Pepper, and I hope that Google will eventually eliminate this unnecessary duplication of functionality.
From my reading of it, pepper.js can only support a subset of Pepper's complete capabilities. At a high level, it is missing:
- threads
- memory mapping
- memory protection
There's also stuff like this in pepper.js that clearly demonstrates a lack of parity: // The Web Audio API currently does not allow user-specified sample rates.
var supportedSampleRate = function() {
return createAudioContext().sampleRate;
}
Also pepper.js is filled with chunks of code like: var FileRef_GetFileSystemType = function() {
throw "FileRef_GetFileSystemType not implemented";
};
var FileRef_GetName = function() {
throw "FileRef_GetName not implemented";
};
var FileRef_GetPath = function() {
throw "FileRef_GetPath not implemented";
};
var FileRef_GetParent = function() {
throw "FileRef_GetParent not implemented";
};
var FileRef_MakeDirectory = function() {
throw "FileRef_MakeDirectory not implemented";
};
var FileRef_Touch = function() {
throw "FileRef_Touch not implemented";
};
I don't know enough about these APIs to say whether this is just incomplete or whether these Pepper calls can't be reasonably implemented on Web APIs, but pepper.js seems far from a demonstration that Pepper is "effectively equivalent" to Web APIs.I understand not wanting to re-invent the wheel, but I don't think we should bake a bunch of LLVM-isms into something that should be designed to run on browsers for the next 20 years. Basically, the whole PNaCl spec feels way too half-baked for something that should be a standard -- sort of how I felt about embedded SQLite into web standards as the spec and reference implementation (WebDatabases, shiver).
I prefer asm.js's approach over PNaCl. I'd also be happy if the browser vendors came up with a new bytecode from scratch as well, designed for the web.
[1] https://developers.google.com/native-client/dev/reference/pn...
The same is likely to happen to PNaCL. It will probably survive for a while in Chrome, as it may be useful for writing ChomeOS specific apps, but it will never be adopted by any of the other browser vendors. ASM.js runs just fine in other browsers, the only difference is that they don't implement the stricter subset and same optimizations as Firefox does, so it's a lot more likely to catch on, as people can write cross-platform ASM.js right now.
This leaves them in roughly the same place; write code that will be heavily optimized for one of the browsers, then include a compatibility layer that will make it runnable in all of the others. Without making an argument as to which underlying approach is better, I see no clear upper-hand from the perspective of compatibility.
What somebody needs to do now is define another language that compiles to both PNaCl and asm.js-suitable languages, and offer a deployment mechanism that correctly uses one or the other when in a browser-optimizable situation. Nothing beats too many standards like adding another standard to unify them. ;)
One of the big differences between ASM.js an PNaCl is that ASM.js just exposes ordinary standardized Web APIs, while PNaCl gives you the Pepper API, which is basically an entirely Chrome specific API. That means that rather than just using Emscripten and compiling with two output targets (PNaCl and ASM.js) which call the same APIs, you need to do a wrapper layer on one or the other (emulating PNaCl with standard Web APIs, or vice versa, or having some other intermediate layer that abstracts over both). The whole point of ASM.js is to leverage existing standardized infrastructure, while PNaCl just exposes what's convenient to expose in Chrome, while likely being considerably more expensive for other browser vendors to implement.
This is a lot like Filter Effects in IE. Rather than specifying a reasonably portable syntax, they defined something that was build specifically on some random subset of DirectX filters, and pretty much impossible to implement anywhere else without implementing a large amount of DirectX. While other browsers eventually released most of the same things in a portable manner, there was a while where you had to either implement both or use some kind of wrapper of one over the other.
While I think that it's a good thing that Google has spent time experimenting with and building NaCl and PNaCl (in general, you need ad-hoc single engine experimental implementations that people can play around with in part to figure out what will actually work for authors and is actually implementable, like canvas was, or various CSS3 effects over the years), it's a standardization dead end, and it would be nice if they would spend their effort on trying to extract something that could be standardized from it and ASM.js, rather than enabling it for web pages so it'll become another single-vendor technology that leaves others as second-class citizens.
This kind of vendor lock in is out of line with promises of openness and supporting standards that Google has made in the past, and especially concerning since they're selling hardware that only runs Chrome. Between locking people in to a single browser on that platform, and a single browser if they target PNaCl (with maybe second-class support for other browsers via Emscripten and pepper.js), this is starting to remind me of what a certain other company did when they had the sleek, fast new browser that was trouncing the big buggy slow incumbent.
That made me laugh. You write code that is supposed to compile to native code, only to have it compiled to javascript instead. It's a crazy world we live in.
I would actually really like this, if defined as an isomorphism to asm.js. (asm.js core operations are pretty simple, it's only the JavaScript syntax that is funny.) Anyone can do it. Write a compiler in JS that compiles this WebBytecode to asm.js (and PNaCl if you want, though I'm not sure if you can dynamically generate PNaCl at runtime from JS) and evals it. You could then ship apps with this bytecode today and have them work in all browsers, and it would be, effectively, completely standards-based since the asm.js semantics would be normative and the asm.js semantics are defined by the ES6 draft spec. You'd be able to ship a clean bytecode representation, unsaddled with the legacy baggage of JavaScript or LLVM, and cross-browser compatibility with what could be, if implemented properly, a tiny stub loader.
The biggest hurdle to getting it working in PNaCl would be wrapping the Web APIs in the Pepper APIs as an "inverse pepper.js", but that should be done anyway as any app that wants to target the standards-based Web APIs and the Google-specific, nonstandard Pepper APIs will want this.
I feel like both PNaCL and asm.js are a kludge in search of a problem. I just don't see either of these winning over say, DICE to implement Battlefield 4 in a browser, or Valve for the next Half-Life franchise. Triple-A developers don't want to leave performance on the table, and running your code inside of a browser virtual machine, even a C-based sandboxed one virtually guarantees that.
Asm.js might be vitally important for a platform like Firefox OS, but I doubt either PNaCl or Asm.js will ever be something the drive by web bothers with, because the kinds of applications that need native levels of performance are also the ones native developers are most likely to do native platform specific ports for. That is, having to recompile and port from Win32 to OSX to Linux is worthy tradeoff vs losing 20-50% performance off the bat, not to mention the different purchasing behaviors of Web users vs console or native mobile users.
Seriously though. Stuff like this is what made me quit Chrome. Too much non-standard Google nonsense in what is supposed to be a standards-compliant web-browser.
It just feel wrong.
Active X, AFAIR, was portable in true Henry Ford manner - running everywhere as long as it's a Wintel box with Internet Explorer.
I ran all the same Active X controls on my WAMD box you did on your Wintel.
Or am I missing something about the Windows/Intel combination?
Anecdote: I switched to Mac (Mintel? Mactel?) in 2007. Prior to that, my 486DX4 100 (circa 1995) was the last Intel I used.
</offtopic>
Although, indeed, Intel lost the control when AMD introduced AMD64. :) But this is really getting offtopic.
Wintel is a portmanteau of Windows and Intel, referring to personal computers using Intel x86 compatible processors running Microsoft Windows.
http://www.microsoft.com/en-us/news/press/1996/oct96/macpr.a...
Every browser vendor experiments with new ideas, only because of this we're getting nice things as the results.
Seriously, the absence of a published standard from a credible and relevant standards body would be my primary objection to the phrase. Barring that, de facto standardization would be indicated by multiple interoperable implementations from more than one vendor and widespread adoption. LLVM IR and PNaCl are, at best, documented. That's better than undocumented, but it's a long way from standardized.
I never said asm.js is standardized. ECMA/JavaScript is, though, and asm.js is just a well-defined conventional subset of JS. There doesn't need to be a standard.
I'm very excited by the idea of being able to write an app that "just works" across a ton of platforms using JS and HTML5, with compiled code sprinkled in for performance-critical portions. Projects like AppJS have been working toward this already, but with PNaCl, a big missing piece can finally be filled in.
Web Workers are a step in the right direction, but they're incredibly limited by design because of the inability to share memory across threads. The requirement of copying data across threads means that parallelizable tasks involving small operations over large chunks of data often don't benefit from using Web Workers. Unfortunately those tasks make up a large percentage of situations where parallel processing is useful.
It's important to emphasize that PNaCl is a platform. We currently provide front-ends for C and C++, but nothing prevents you from writing your own, for your own language (or an existing one). As long as you emit PNaCl bitcode, Chrome will run it for you. The PNaCl bitcode has a definition here - https://developers.google.com/native-client/dev/reference/pn... - and we're working on making it more precise.
One day, the browser will be used again just for documents. That day, I'll be very happy.
I'd like to see the benchmarks before assuming that, but if this leads to letting me use Haskell in the browser, I'll be all over it.
Also, Native Client, but apparently not PNaCl, supports SIMD, while asm.js does not.
Of course, both PNaCl and asm.js are evolving, so asm.js may be able to eventually support those features somehow, and PNaCl may get additional features.
Some information about features PNaCl supports are here: https://developers.google.com/native-client/dev/faq
EDIT: And pepper.js is essentially a response back to asm.js and its "run, albeit with less performance optimization, on any modern JS engine".
Both are basically intended as a target for LLVM-compiled code, so lots of similarities, but the main difference is that asm.js is a subset of JS so it runs in any JS engine, while PNaCl is different. Aside from that, there are lots of technical differences, but it's hard to say which actually matter in the long run. To quickly summarize, right now asm.js tends to run a little more slowly than PNaCl but start up a little more quickly. But engineers on PNaCL and on JS engines intend to shrink those differences over time, and there is no reason in principle why they won't succeed.
To judge for yourself, you can see some comparisons between PNaCl and asm.js in these two sites:
http://www.flohofwoe.net/demos.html
http://trypepperjs.appspot.com/
My impression is that the perf differences are not that noticeable already. For example, the bullet demo in the second one seems to run slightly faster in PNaCl than asm.js. However, profiling shows that 65% of time is spent in three.js rendering code, not in asm.js, so perhaps rendering differences account for most of the disparity, and it mostly isn't comparing asm.js to PNaCl.
Take this naive fibonacci function: function fib(n) return n<2 and n or fib(n-1)+fib(n-2) end print(fib(30))
On my machine, it completes in less than a second on PNaCl, but takes nearly 10 seconds to complete in emscripten.
http://kripken.github.io/lua.vm.js/repl.html
But even that is already out of date ;) just this week I found that I was building Lua with a bad choice of optimization flags. We include Lua VM benchmarks in the emscripten test suite, so for the latest numbers (with the proper optimization flags), see
https://docs.google.com/spreadsheet/ccc?key=0AkuGewEm05tZdFd...
It's possible to run the Lua VM in JS at only about 50% slower than a native build.
edit: fix link
Regarding lua, I updated the lua vm project, and tried your fibonacci function from before in the repl
http://kripken.github.io/lua.vm.js/repl.html
Looks like in both firefox and chrome it runs in about a second in JS, which feels about the same as the time it takes in PNaCl in chrome on
The point of PNaCl was to overcome or remove some of the constraints that come with the JavaScript language, like the lack of a concurrency model. This necessitates a new runtime. Since a new runtime was required anyways, Google decided to expend the engineering effort to make it as similar to native code as possible in terms of capabilities and performance, while also maintaining security.
The point of asm.js was to not include another runtime in the browser, but still meet the needs of the programs that PNaCl was trying to serve. Because it plays within the bounds of JavaScript it doesn't meet all the needs that PNaCl does (again, like concurrency), but it still allows native-like programming.
Edit: to elaborate: do a simple simulated annealing on a 200x200 array in JS - it's measured in seconds on my laptop. I wrote a program in JS that did this (image segmentation, fg/bg seperation for recognition) and abandoned it because of speed issues.
I did some serious optimization when I wrote it. There was a "best practices" for V8 that shedded some light on the background of JS variable allocation, I followed it and got a serious boost. Also did lookup tables instead of runtime math with exp/log functions. But in the end: hit several worst case images that took more than 12s, which was a gap that couldn't further be reduced through optimization.
But you're absolutely right, I should redo it in PNaCl.
When you start appropriating other peoples' computers for your own purposes, secretly, without their approval, that's called a bot net.
By fertile pasture I mean that both malevolent and benevolent communities will support this. This could see a lot of optimization if open sourced (is it?).
From an application security point of view, PNaCl -- and the general trend of packing everything into browsers -- is not good. The first rule of security is to keep things small and simple. A browser with a built-in compiler is no longer a browser.
If Google had its way, phones would just be dumb bootloaders for operating systems downloaded on the fly from their cloud.
The PNaCl thing actually makes it more realistic to actually install a "Web App" inside Chrome and use it independent of an internet connection. The browser is lagging well behind Android and iOS in terms of user experience. Efforts like PNaCl and asm.js help to restore the balance.
All browsers include compilers already, by the way.
I know everyone loves to hate on Java, but I'm always amazed by some of the wacky things people say ...
Dart[1] is high-level, and has a clean, fast VM implementation. Also, ARM support[2].
[1] https://www.dartlang.org/ [2] https://code.google.com/p/dart/source/browse/branches/bleedi...
1. http://thenextweb.com/google/2013/07/17/google-is-holding-a-...
One thing I am concerned about is, since PNaCl is essentially yet another platform, how Google (or anyone) is going to manage the host of supporting tools required. Tools like dependency management, libraries, process control etc.
By the way, Google has already proven their "platform-creation" skills with Android.
The new part of PNaCl is that you don't have to recompile for each target architecture. Among other things, if they push hard for this for desktop developers on the Chrome App Store, then suddenly they have a large number of things that work on Chromebooks without demanding that developers recompile.
PNaCl eliminates a dev's actions to recompile.
PNaCl removes the need to compile different x86 vs. ARM binaries for NaCl.
A more significant difference is, however, that NaCl is restricted to the Chrome web store, while PNaCl is available on the open web. You can have a PNaCl module your web app, on your website/domain today, and Chrome 31 (and later) will run it.
There are already a few games on NaCl, like Don't Starve[0] that work on x86/x86_64-based chromebooks. They just don't run on ARM-based chromebooks -- which is one of the incentives for PNaCl.
IIRC, NaCl could only run in Chrome Web Apps precisely because it was platform-dependent. It looks like PNaCl will also allow ActiveX/Flash-style embedding.
Anyway running in Chrome product sandbox is nothing attractive. For the web, I would bet on Emscripten + asm.js which is a lot more portable.
Not all of them have GPL licenses, plus it is only fair to pay people for their work.
Also I haven't argue payment itself is bad. Go back and read carefully my reply. Fair trade is good, and I would gladly pay for good product.
You mentioned targeting the browser with C++ for portable applications.
For me the place of native code is at the OS level, and the browser should be left alone for plain interactive documents, instead of Frankenstein VM.
Hence my short reply with a list of native frameworks.
It has nothing to do with licenses.
My original intention was using HTML as a GUI toolkit layer, and I realized that was wrong idea with PNaCL. It's exactly opposite concept. It's my mistake. I'm sorry for that.
Wow. now I see PNaCL is really completely useless except for Google's API dominance.
What really happened, they reached a stable version or something?