5 ms·
> OdinMonkey is a hammer that will kill incentive to optimize JavaScript that humans write. Eh, I'm not worried about this. Many apps will have no reason to m
by haberman 14y ago
> OdinMonkey is a hammer that will kill incentive to optimize JavaScript that humans write.
Eh, I'm not worried about this. Many apps will have no reason to migrate to asm.js, and for as long as some big and important apps are written in JavaScript, there will be incentive to optimize plain JavaScript.
JavaScript and other dynamically-typed languages exist because in many cases they are the best and most convenient way to write apps. But suppose this weren't true; suppose that in the long-term developers started favoring statically-typed languages for web apps, either because of performance or because of usability (Eclipse-like IDE convenience; hard to provide in a dynamic language). Is the author saying that we should artificially prop up usage of dynamic languages by taking away some of the inherent performance benefits of static languages? That doesn't sound like the best way to achieve technical excellence in the long term.
In the marketplace of ideas and technologies, let things succeed or fail based on their demonstrated merit, rather than trying to pick winners and losers based on our preconceptions.
> Somebody might say that [my proposed bytecode] does not run everywhere. Nope. It does run everywhere: just take JavaScript and write a simple one pass translator from this bytecode to JavaScript.
You can think of asm.js as just that; a one-pass translator of an implicitly-defined bytecode to JavaScript. If you want to view/edit it as a more traditional-looking byte-code, you can easily implement a YourBytecode<->asm.js compiler. It just so happens that asm.js is a backward-compatible representation, so works more conveniently as the standardized wire encoding.
(I have not studied the asm.js spec in detail, but I've seen pcwalton describe it as an alternate encoding of LLVM bitcode, so I suspect that the idea of implementing a YourBytecode<->asm.js compiler is actually reasonable given the asm.js definition).
- niggler 14y ago" If you want to view/edit it as a more traditional-looking byte-code, you can easily implement a YourBytecode<->asm.js compiler." There are quite a few hurdles, and some of them will be resolved with some stuff Mozilla has proposed in ES6. But as it stands now, you can't use CLR IL bytecode or even JVM bytecode.
- glhaynes 14y agoYou couldn't (reasonably) compile the CLR or the JVM to asm.js? I'd assume you could, which would seem to point toward a translation of bytecodes (since that's what the asm.js-hosted CLR/JVM would be doing) being feasible…
- niggler 14y agoYou can't because both are garbage collected, which asm.js is unable to access (unless you wrote your own garbage collector) At the end of the day, asm.js uses some code patterns (like taking bit-or with 0, where the spec mandates that it occurs as if the data is coerced to 32 bit integers) to optimize performance of those operations. It is only capable of doing so when you strip away most of those features which make JS a really nice language to write code in.
- glhaynes 14y agoBut at that point the VM-atop-asm.js-atop-the-JavaScript-engine would be the thing doing the GC against its own asm.js-provided heap. (Right?) Perhaps performance would be awful, though I guess I don't immediately see why: if asm.js can get reasonably close to native speed (within 2x, I think I've read?) and .NET/Java can get within a comparable distance of native, then the two together should be slower, but not unusable for many things, I'd think. Upon seeing your edit: much of the speedup also comes from the lack of dynamicity, too, from my understanding.
- niggler 14y ago"VM-atop-asm.js-atop-the-JavaScript-engine would be the thing doing the GC" "much of the speedup also comes from the lack of dynamicity, too." In the language, JS gives you no control over its underlying GC. Every single assumption that asm.js leverages depends on the determinism, and introducing a GC into the mix really messes with AOT optimizations
- glhaynes 14y ago
- pcwalton 14y agoI should qualify my statement with some caveats: * asm.js has a very primitive type system, unlike LLVM bitcode. I think this is better for a distribution format; the complex types make sense for compiler IR optimizations but not so much for distribution after the optimizations are already done. * asm.js doesn't have goto, unlike LLVM bitcode. I'm told that this doesn't seem to matter much in practice, as the Relooper is quite refined now. However, I'm certainly willing to believe that there are some oddly-shaped CFG's that this will hurt. Perhaps JS will need goto. * asm.js doesn't have 64-bit types. This is unquestionably unfortunate, as it will need 64-bit types to achieve native parity. (Of course, JS needs 64-bit types anyway—it's important on the server, for instance.) * asm.js doesn't have SIMD, unlike LLVM which has support for SIMD with its vector types. This will need to be added on to be competitive on some workloads. This is a good opportunity for collaboration between Dart and JS, as Brendan pointed out. Regarding the original post, (and speaking only for myself, not my employer) I actually agree with mraleph to some degree. From an aesthetic point of view I don't like the subset approach as much as anyone. But if V8 doesn't implement asm.js AOT compilation, ignores the "use asm" directive, and achieves the same performance as Odin, then that's actually a good outcome in my mind. At least asm.js will have fulfilled the role of an informal standard that engines and compiler writers alike can agree to target for maximum performance.
- grayrest 14y ago> Perhaps JS will need goto I was under the impression that labeled break/continue were the equivalent.
- pcwalton 14y agoYou can use labeled break and continue for a lot. That said, there is some irreducible control flow that the Relooper falls down on. It's quite rare in practice, though—with if, while, break, continue, labeled break, and labeled continue, the Relooper can reloop nearly all control structures seen in actual code. But, as I mentioned, I'm willing to believe you can come up with a benchmark where you'll need goto.
- DannyBee 14y ago
- mraleph 14y ago> there will be incentive to optimize plain JavaScript I am not that worried about average JavaScript code. I am more concerned about computational cores that people will start rewriting to asm.js. Or here is another question: how do you keep incentive to optimize Emscripten generated code so that eventually you can kill "use asm" and go full speed without it? > You can think of asm.js as just that; a one-pass translator of an implicitly-defined bytecode to JavaScript. No, when I said about one pass translator, I meant it should run on the client. asm.js is not just that.
- haberman 14y ago> Or here is another question: how do you keep incentive to optimize Emscripten generated code so that eventually you can kill "use asm" and go full speed without it? Why is that important? I don't get it. Emscripten -> JS is lossy; it throws away information that the code generator could use to generate more efficient code. A clever JIT can re-discover that information by observing the code in action. And sure, that's a satisfying challenge from a VM implementor's perspective, why is it a priori worse to just tunnel that information through via asm.js rather than throwing it away? Even if the VM is perfect at this, there is a non-zero runtime cost that, I would expect, scales linearly in the size of the application.
- mraleph 14y ago> Why is that important? I don't get it. For various reasons. I believe it can be done, thus because it can be done I don't see why it should not be done. Why keep two front-ends (two parsers even!), two separate IR generators etc in the system if you can have one? I also think that such code can occur and occurs in real world applications as well. And I want any JS code go faster to its limit, without requiring people to rewrite anything. It is true that dynamic compilation incurs certain overhead and requires warm up. But it is also true that AOT compilation is not cheap either (that is why a special API to cache generated code is being suggested).
- azakai 14y ago> I am not that worried about average JavaScript code. I am more concerned about computational cores that people will start rewriting to asm.js. > Or here is another question: how do you keep incentive to optimize Emscripten generated code so that eventually you can kill "use asm" and go full speed without it? I hope that some JS engine does no special asm.js optimizations, but at the same time achieves the same speed. That would be both an amazing technical achievement, and a very useful result (since presumably it would apply to more code)! :) Btw, I actually was pushing for that direction in early asm.js-or-something-like-it talks. So I think I see where you are coming from on this matter, and most of the rest of your post as well - good points. However, I strongly believe that despite the correctly-pointed-out downsides, asm.js is by far the best option the web has: We need backwards compatibility + near-native speed + something reasonably simple to implement + minimal standardization difficulties. I understand the appeal of the alternatives, but think asm.js is far closer to achieving all of those necessary goals.