6 ms·
This seems very much targeted at emscripten and not to cross-compilers that start with GC'ed languages like GWT, Dart, ClojureScript, et al. If you are cross-co
by cromwellian 14y ago
This seems very much targeted at emscripten and not to cross-compilers that start with GC'ed languages like GWT, Dart, ClojureScript, et al. If you are cross-compiling Java or C# to asm.js, you don't really want to manage memory manually. I work on GWT, and asm.js as an output target is very interesting to me (I've worked on a number of performance Web games using it, GwtQuake, AngryBirds, etc), but the starting assumption is GC, so I want to leverage non-boxed numerics, and all of the other nice stuff, but don't want to stuff everything into a TypedArray.
It's also unclear to me how this solves the problem of startup time on mobile. A giant glob of Javascript takes a non-trivial amount of time to load even on today's fastest smartphones. The spec seems to argue that Browser VMs could recognize asm.js and if I read between the lines, employ snapshoting the app and caching it for later quick startup?
In all likelihood, the majority of asm.js outputs would be actually be non-human readable output of optimizing cross-compilers, so there isn't much benefit from having a readable syntax that humans could read, so what's the real justification for using JS as an intermediate representation over say, a syntax specifically designed for minimum network overhead and maximum startup speed? Seems like it might be worthwhile for Mozilla to also work on efficient representations of asm.js that minimize this overhead. The usual response is minify + gzip, but it's not a panacea.
- azakai 14y ago> This seems very much targeted at emscripten and not to cross-compilers that start with GC'ed languages like GWT, Dart, ClojureScript Those languages can benefit as well (but might not make sense in all cases). You can compile Java to C and then to JS, here's a demo http://xmlvm.org/html5/ http://xmlvm.org/html5/ Yes, this has downsides like compiling your own GC. For GC heavy code it might be slow. But for raw computation you would probably get faster results than source-to-source like GWT does - you get LLVM optimizations, and you get asm.js which is easier for JS engines to run quickly. > It's also unclear to me how this solves the problem of startup time on mobile. Yeah, that is a problem. It's a problem on normal JS too, and also for things like PNaCl. Only shipping final native binaries can fully avoid that (but that is nonportable). > The spec seems to argue that Browser VMs could recognize asm.js and if I read between the lines, employ snapshoting the app and caching it for later quick startup? Yes, that is one possibility. It could work for normal JS too, I'm not sure why it hasn't been done yet. Worth investigating. > In all likelihood, the majority of asm.js outputs would be actually be non-human readable output of optimizing cross-compilers, Yes. > so there isn't much benefit from having a readable syntax that humans could read, so what's the real justification for using JS as an intermediate representation over say, a syntax specifically designed for minimum network overhead and maximum startup speed? The justification is that asm.js code will work, right now, in all browsers. (And it can fairly easily be optimized by them to run much faster than compiled code in JS.) Any new format would require standardization and take a long time. asm.js is just JS. For network transmission, we should implement a special minifier for it (written in JS of course).
- nnethercote 14y ago> asm.js is just JS. This needs to be shouted from the rooftops. This is the single most important constraint of the project and also its greatest strength. So asm.js isn't the magical perfect browser bytecode that everyone on HN wants -- and which would have all manner of flaws if it actually existed in concrete form, rather than a platonic ideal in people's heads -- but that's a completely unrealistic goal anyway. But asm.js is usable in all browsers immediately. asm.js is just JS.
- skatepark 14y ago> But asm.js is usable in all browsers immediately. asm.js is just JS. A magic JS-based bytecode that's usable in all browsers immediately isn't useful if it isn't fast. Which it isn't, because it's a JS-based bytecode executing under existing JS engines. So now we have apps that perform incredibly poorly when run on a browser without "asm.js" support, and a rather ridiculous bytecode format that will have to be parsed natively to run reasonably quickly, with a fair bit more complexity for every layer in the development and runtime stack because they insist on keeping it as valid JS syntax.
- deleted 14y ago[deleted]
- coldtea 14y ago>"A magic JS-based bytecode that's usable in all browsers immediately isn't useful if it isn't fast." Says who? Python, for one, is plenty usable, and is not fast. >Which it isn't Says who? JS engines are close to Java/C in speed, and 10x faster thn Ruby, Python et al. V8 is faster or as fast than statically compiled Go or JITed Julia, for example...
- anon1385 14y ago>Python, for one, is plenty usable, and is not fast. In any environment where I might currently choose to use Python I also have the option to use something else for parts of the project where Python proves to be too slow. Will FirefoxOS provide such an escape hatch? >JS engines are close to Java/C in speed 'close' is a pretty vague term. For a lot of tasks Ruby is 'close' enough to C that the difference doesn't matter. For a different set of tasks Java is not 'close' enough to C (or C+asm) to be a viable choice and neither is Javascript. I'd also like to point out that battery life does matter, and using at least twice the CPU cycles for most tasks isn't conducive to good battery life.
- pcwalton 14y ago"I work on GWT, and asm.js as an output target is very interesting to me (I've worked on a number of performance Web games using it, GwtQuake, AngryBirds, etc), but the starting assumption is GC, so I want to leverage non-boxed numerics, and all of the other nice stuff, but don't want to stuff everything into a TypedArray." I'll let dherman elaborate in more detail, but he is working on it. :) "The spec seems to argue that Browser VMs could recognize asm.js and if I read between the lines, employ snapshoting the app and caching it for later quick startup?" This is really a problem with any portable code delivery format that wants to run compiled code. You either have to stick to native code, in which case you aren't portable, or you have to compile on the client, which adds startup time. Caching of compiled artifacts is going to be necessary in any portable solution, and I don't see any reason off the top of my head why this would be particularly different for asm.js. "Seems like it might be worthwhile for Mozilla to also work on efficient representations of asm.js that minimize this overhead. The usual response is minify + gzip, but it's not a panacea." I agree, and I've talked to Alon about this. I think that it would be an interesting project to develop a format that compresses asm.js down as small as possible. Then you can simply uncompress and eval on the client side to ensure backwards compatibility.
- cromwellian 14y agoJava went through a similar issue with their pack200 format. I am not privy to where all the time is spend in mobile JS startup (parsing, etc). It seems like using some kind of special JS precompressor would both benefit entropy coding as well as allow a faster parser, but I've seen it turn out to be a wash in the past. :( However, even if you could reduce network bandwidth, it would be a win for people's data plans and batteries. :)
- BrendanEich 14y agoObviously video and similar compression is a counterexample, but I usually lose when betting against gzip. /be
- dherman 14y agoWe have plans! First of all, we do care very much about supporting compilers for managed languages like Java and C#, but we're starting with this first version that only supports zero GC and atomic primitive types. We have plans to grow outwards from there to support structured binary data, based on the ES6 binary data API, and controlled interaction with the GC. Luke has ideas about how to do this without losing the predictable performance for lower-level compilers like Emscripten. We do have plans for startup time. I hope to pitch a very small, simple API for a kind of opaque compiled Function. Internally we've been calling it FunctionBlob (we'll bikeshed the name later). The idea is that `new FunctionBlob(src)` is almost identical to `new Function(src)` except the object is (a) an opaque wrapper that can be converted to a function via `fblob.toFunction()` and (b) entirely stateless and therefore compatible for transfer between Workers as well as offline storage. This would essentially make it possible to do things like background compilation of asm.js on a Worker thread, and caching of the results of compilation in offline storage. That way next time you startup you don't have to download or optimize the source. (This could work especially well with the app experience where you could perform these download/optimize steps as part of the installation process.) As for the use of JS, this is purely pragmatic. The code works today in browsers, so people can start using it and it works -- and even quite fast; Emscripten is already shockingly performant in Firefox and Chrome -- but over time it'll see better and better optimization.
- cromwellian 14y agoPresumably, if it was a blob, it could also be stored in local storage/indexdb/filesystem API? Is the internal format supposed to be architecture neutral, or dependent? I can see arguments for either, but if it were neutral, than the blob conversion could be done offline/statically on the server, and downloaded by the client dynamically (e.g. XHR to fetch function blobs). If it were architecture dependent, then I could see advantages as well, letting the browser vendor choose the optimal form of the blob. This would potentially yield better performance, but you wouldn't be able to host blobs on the server. Anyway, cool idea.
- dherman 14y agoI was only thinking that it would be internal. Your server point is good, but I think way, way harder, and kind of starts the whole project back at the beginning: how to design a standard, efficient, optimized bytecode format. So I think it's probably not really feasible. Not the same, but an additional optimization you can do is incremental compilation. Because you have JavaScript's eval, you can download the code a bit at a time and optimize (and cache via FunctionBlob) each piece.
- andhow 14y ago(Luke Wagner from Mozilla here.) > This seems very much targeted at emscripten and not to cross-compilers that start with GC'ed languages like GWT, Dart, ClojureScript, et al. That's correct, although one could implement a garbage collector on top of the typedarray heap (we have working examples of this). There are some limitations to GCing the typed array manually, though, such as not taking advantage of the browser's ability to better schedule GCs. Looking further in the future, though, it would be completely reasonable to extend asm.js to allow the super-optimizable use of the upcoming BinaryData API [1] in the style of JVM/CLR-style objects. Again, though, this is speculative; BinaryData isn't even standardized yet. > It's also unclear to me how this solves the problem of startup time on mobile. We have several strategies to improve this. The "use asm" directive, in addition to allowing us to produce useful diagnostic messages to devs when there is an asm.js type error, allows us to confidently attempt eager compilation which can happen on another thread while, e.g., the browser is downloading art assets. Looking farther in the future again, we could make some relatively simple extensions to the set of Transferrable [2] objects that would allow efficient programmer-controlled caching of asm.js code including jit code using the IndexedDB object store. > In all likelihood, the majority of asm.js outputs would be actually be non-human readable output of optimizing cross-compilers, so there isn't much benefit from having a readable syntax that humans could read, so what's the real justification for using JS as an intermediate representation over say, a syntax specifically designed for minimum network overhead and maximum startup speed? Before minification, asm.js is fairly readable once you understand the basic patterns, assuming your compiler keeps symbolic names (Emscripten does). The primary benefit is that asm.js runs right now, rather efficiently, in all major browsers. It also poses zero standardization effort (no new semantics) and rather low implementation effort (the asm.js type system can be implemented with a simple recursive traversal on the parse tree the generates IR using the JS VM's existing JIT backend). This increases the chances that other engines will adopt the same optimization scheme. A solution for native performance is only a solution if it is portable and we want to maximize that probability. > The usual response is minify + gzip, but it's not a panacea. In addition to minify+gzip, one can also write a decompressor in asm.js that unpacks the larger program. Also, see [3] for how minified gzipped Emscripten code is comparable to gzipped object files. [1] http://wiki.ecmascript.org/doku.php?id=harmony:binary_data http://wiki.ecmascript.org/doku.php?id=harmony:binary_data [2] http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#transferable http://www.whatwg.org/specs/web-apps/current-work/multipage/... [3] http://mozakai.blogspot.com/2011/11/code-size-when-compiling-to-javascript.html http://mozakai.blogspot.com/2011/11/code-size-when-compiling...