More thoughts on asm.js

551 views
Skip to first unread message

Cogman

unread,
May 17, 2013, 11:58:15 AM5/17/13
to mi...@dartlang.org
So the last discussion, it looked like dart2js wasn't going to be targeting asm.js anytime soon.  One of the main reasons (from my untrained eye) was the lack of support for GC.

So, here is what I'm wondering. How hard would it be to instead partially support it when GC doesn't matter.

For example, lets say a function doesn't mutate any state outside of the function itself (all new objects stay in scope and it doesn't touch class level objects.)  It seems to me that would be a perfect function to target to asm.js. In that case, the only thing that really matters is the output of the function.  GC isn't a big issue because at the end of the function everything should be freed up anyways.

IDK, some extra work might have to be done in the case that the return type is an object, but I think it may work.  I've never written a compiler, so I don't know how hard it would be to analysis if a function is modifying global state or not.

Thoughts?

Bob Nystrom

unread,
May 17, 2013, 12:20:55 PM5/17/13
to General Dart Discussion

On Fri, May 17, 2013 at 8:58 AM, Cogman <cog...@gmail.com> wrote:
For example, lets say a function doesn't mutate any state outside of the function itself (all new objects stay in scope and it doesn't touch class level objects.)  It seems to me that would be a perfect function to target to asm.js. In that case, the only thing that really matters is the output of the function.  GC isn't a big issue because at the end of the function everything should be freed up anyways.

Note that asm.js doesn't currently support strings or other objects either. Or closures or methods. Or external functions of any sort except for a specially configured set of bindings.

At least in its current form, I think that means the set of Dart functions that could compile to something asm.js-safe is actually surprisingly small.

Cheers,

- bob

Ladislav Thon

unread,
May 17, 2013, 12:36:34 PM5/17/13
to General Dart Discussion


>> For example, lets say a function doesn't mutate any state outside of the function itself (all new objects stay in scope and it doesn't touch class level objects.)  It seems to me that would be a perfect function to target to asm.js. In that case, the only thing that really matters is the output of the function.  GC isn't a big issue because at the end of the function everything should be freed up anyways.
>
>
> Note that asm.js doesn't currently support strings or other objects either. Or closures or methods. Or external functions of any sort except for a specially configured set of bindings.
>
> At least in its current form, I think that means the set of Dart functions that could compile to something asm.js-safe is actually surprisingly small.

And note that V8 people were able to optimize some of the patterns that are common in asm.js without actually resorting to recognizing asm.js. Or at least that's my interpretation of what was said at IO keynote. Other JavaScript implementers should take this as an example, instead of inventing crazy JS subsets, if you ask me.

LT

Alex Tatumizer

unread,
May 17, 2013, 1:21:09 PM5/17/13
to mi...@dartlang.org
What asm.js means IMO is this: mozilla figured out that performance of javascript will never be up to expectations, and they decided to form a kind of symbiosis with C. Directly supporting link with C for some reason looked politically incorrect (they could take nacl instead), so they decided to invent another low-level language and make it look like javavscript.

And now dart is in a fix. Something has to be done about asm.js.

The way out IMO would be incorporating some low-level language (e.g. by forming simbiosis with C proper), which can be compiled to asm.js for use in browsers not supporting dart. Or hope that all browsers will support dart eventually.

There's a problem anyway, it's real IMO.




Bob Nystrom

unread,
May 17, 2013, 1:34:14 PM5/17/13
to General Dart Discussion
On Fri, May 17, 2013 at 10:21 AM, Alex Tatumizer <tatu...@gmail.com> wrote:
What asm.js means IMO is this: mozilla figured out that performance of javascript will never be up to expectations, and they decided to form a kind of symbiosis with C. Directly supporting link with C for some reason looked politically incorrect (they could take nacl instead),

My guess is, they saw:

1. Game developers wanting to get their games written in C/C++ to run on the web.
2. NACL as one path to do that which they don't like.
3. Emscripten not giving enough performance on its own.

So they made asm.js to enable C/C++ -> JS compilers to output faster code.
 
so they decided to invent another low-level language and make it look like javavscript.

Right. In particular, it lets them add a new language that also happens to coincidentally have the same syntax and semantics as JavaScript (but not the same performance) so they can support it in Firefox without breaking any existing web standards. They can add asm.js to Firefox without the negative implications of adding something vendor-specific to their browser since performance isn't part of most standards.  


And now dart is in a fix. Something has to be done about asm.js.

I don't believe asm.js in its current incarnation affects Dart, JS, or any other high-level language. It's a compiler target for manually-managed-memory languages.


The way out IMO would be incorporating some low-level language (e.g. by forming simbiosis with C proper), which can be compiled to asm.js for use in browsers not supporting dart. Or hope that all browsers will support dart eventually.

There's a problem anyway, it's real IMO.

asm.js has gotten a ton of attention, which is very exciting. They've done a great job of presenting it to users in a compelling way and for the use cases where it makes sense, it's quite cool. We could learn a lot from how well they engage with the web community.

In practice, though, I don't think it will be helpful for most web apps. If it matures to the point where it supports GC, arbitrary objects, etc. that may change. But right now, unless you're building an app in C, or you don't mind making users download an entire garbage collector that's been transpiled to JS and runs on top of the VM's actual GC, I don't think asm.js is likely to be a good fit for you.

In other words, I think it competes with NACL, but not much else. I also find NACL interesting, but similarly narrow in scope. That's just my impression, though.

- bob

Gen

unread,
May 17, 2013, 1:41:08 PM5/17/13
to mi...@dartlang.org
I think we all agree that asm.js is not there to write classic web apps.

It is there to bring C++ (and other) code to the web with maximum performance and a minimum of problems (security or new web standards that take many years).

Alex Tatumizer

unread,
May 17, 2013, 2:32:40 PM5/17/13
to mi...@dartlang.org
> I don't believe asm.js in its current incarnation affects Dart, JS, or any other high-level language. It's a compiler target for manually-managed-memory languages.

It affects dart in the following way.
Suppose Alice and Felix are competitors. Each wants to write a version of some app to run in all browsers. App requires some heavy computations as a part of it (maybe even small part, but critical for performance).
Each has a choice: write in dart, or write in javascript+ (C -> asm.js)

Now assume dart by itself is very fast, and doesn't need any link to low-level languages to be fast (this is yet to be proven, but suppose so). When Felix writes the whole thing in dart, his program runs very well in Chrome. But in Firefox... it's not speedy enough. Because javascript generated by dart2js doesn't utilize performance benefits of asm.js

At the same time, Alice writes in javascript+C. Her code runs very well in Firefox. And in Chrome, too! Because Chrome probably will start supporting asm.js anyway.

That's the point. To counterbalance it, dart needs the "source" for cross-compilation to asm.js. As a consequence, dart VM should support that language, too, natively, otherwise it won't work in dart itself.


Gen

unread,
May 17, 2013, 3:23:21 PM5/17/13
to mi...@dartlang.org
Easy interoperation is a good thing.
Dart in asm.js is probably wasted effort.
asm.js in Dart might be useful.
Although Dart is still uncommon technology.
Companies will favor Javascript/Typescript + C instead of Dart + C.

Alex Tatumizer

unread,
May 17, 2013, 4:35:38 PM5/17/13
to mi...@dartlang.org
It all depends on how good integration with C is.
Never seen a language that was quite good at this kind of integration.
Whoever solves this problem, has very good chances to win I think.



--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new
 
 

Cogman

unread,
May 17, 2013, 4:36:44 PM5/17/13
to mi...@dartlang.org
@Alex

That was more my point. I understand that it might be impossible to put all of dart into asm.js, however, if we can get a portion of it into it it might bear fruit.  Somewhat similar to the concept of letting the compiler optimize for platform specific instructions.


Filipe Morgado

unread,
May 17, 2013, 7:32:25 PM5/17/13
to mi...@dartlang.org
I believe that asm.js currently runs at roughly half the speed of native code (2x the time).

Optimized Dart code (typed_data) apparently beats Java, so we can expect something like 1.2x the processing time of native code.

I'd rather have the Dart team concentrate on the Dart VM than on some doubtful JS-subset cross-compilation.

I'd love to see Dart targeting NaCL, though. But I guess it would need a compiler that cares about static types.

Bob Nystrom

unread,
May 17, 2013, 7:39:21 PM5/17/13
to General Dart Discussion

On Fri, May 17, 2013 at 11:32 AM, Alex Tatumizer <tatu...@gmail.com> wrote:
And in Chrome, too! Because Chrome probably will start supporting asm.js anyway.

That seems like a pretty big assumption to tack on there. If Chrome starts supporting asm.js, then that would be a good signal for us to have dart2js compile to asm.js-friendly code where it makes sense.

If that happens, Felix is in a happier place: his Dart code will automatically get faster if it follows the rules the compiler needs to generate optimized JS. Alice has to take some of her JS, hand-rewrite it in C (no one's idea of a fun time), and then build her own bridge layer so her existing JS code can talk to the emscripten-generated asm.js code.

You could imagine some JS -> JS + automatic asm.js-ification compiler that Alice could use, but such a compiler doesn't currently exist. dart2js already has much of the static analysis required to make something like that tractable, and Dart is a much more amenable language for that kind of analysis.

- bob

jim.trainor.kanata

unread,
May 17, 2013, 7:51:09 PM5/17/13
to mi...@dartlang.org

Alice has to take some of her JS, hand-rewrite it in C


Good grief!  Poor Alice. Stuck translating one error prone legacy language to another error prone legacy language in order to get some performance from her shiny new browser.

Josh Gargus

unread,
May 17, 2013, 9:05:11 PM5/17/13
to mi...@dartlang.org
On Friday, May 17, 2013 4:51:09 PM UTC-7, Jim Trainor wrote:

Alice has to take some of her JS, hand-rewrite it in C


Good grief!  Poor Alice. Stuck translating one error prone legacy language

Since Emscripten takes LLVM bitcode as input, you're not stuck with C/C++... you can (in theory anyway) write in any language with an appropriate front-end compiler. 

 
to another error prone legacy language in order to get some performance from her shiny new browser.

I don't think bug-proneness of the target language is much of a concern.  For example, bug-prone as JavaScript may be, it pales in comparison to writing apps in x86 assembly.


Cheers,
Josh

Josh Gargus

unread,
May 17, 2013, 9:25:31 PM5/17/13
to mi...@dartlang.org
On Friday, May 17, 2013 4:39:21 PM UTC-7, Bob Nystrom wrote:

If that happens, Felix is in a happier place: his Dart code will automatically get faster if it follows the rules the compiler needs to generate optimized JS. Alice has to take some of her JS, hand-rewrite it in C (no one's idea of a fun time), and then build her own bridge layer so her existing JS code can talk to the emscripten-generated asm.js code.

I generally agree with this, as far as it goes, but I think it misses a few things:

Alice won't necessarily optimize by hand-coding her own C... she might also use optimized third-party libraries, or use it as a path to port her existing C++ app.

I think the bridge-layer problem can be solved via a C library that implements an asm.js "ABI" to support interop with regular JS.  In the early days, people might be stuck rolling their own bridge layer, but I wouldn't expect this to be the case for long.

To put this in perspective, I agree that for applications (like web-apps) that are sensible to write in a dynamic, garbage-collected language, asm.js is not a win compared to Dart.  However, the value proposition is better for those few things you'd prefer to write in C++.  Of course, if that turns out to be a big deal, it should be comparatively easy to define an isomorphic "asm.dart" and retarget the Emscripten backend to that.  Or other approaches toward the same end.

Cheers,
Josh


Ladislav Thon

unread,
May 18, 2013, 2:38:50 AM5/18/13
to General Dart Discussion


> Suppose Alice and Felix are competitors. Each wants to write a version of some app to run in all browsers. App requires some heavy computations as a part of it (maybe even small part, but critical for performance).
> Each has a choice: write in dart, or write in javascript+ (C -> asm.js)
>
> Now assume dart by itself is very fast, and doesn't need any link to low-level languages to be fast (this is yet to be proven, but suppose so). When Felix writes the whole thing in dart, his program runs very well in Chrome. But in Firefox... it's not speedy enough. Because javascript generated by dart2js doesn't utilize performance benefits of asm.js
>
> At the same time, Alice writes in javascript+C. Her code runs very well in Firefox. And in Chrome, too! Because Chrome probably will start supporting asm.js anyway.

Felix will probably finish his program a lot sooner than Alice (if we assume feature parity), meaning that Alice have effectively lost before she even began. And if we accumulate a critical mass of such Felixes, other browsers will have to start looking at Dart more seriously.

LT

Gen

unread,
May 18, 2013, 4:04:20 AM5/18/13
to mi...@dartlang.org
I do not think so.
As I had mentioned, the point is not to write Javascript like code using asm.js.

The point is to use existing Fortran or C++ libraries or Lua code or whatever. The Unreal game engine is already already.
Depending on how asm.js evolves and defines its own API standard (maybe concurrency model including C++11 stuff), this could change the browser and server world.
Message has been deleted

Ladislav Thon

unread,
May 18, 2013, 5:49:50 AM5/18/13
to General Dart Discussion


> I do not think so.
> As I had mentioned, the point is not to write Javascript like code using asm.js.

To me, it looks like that for a lot of people, this is exactly the point ("ES6 will make the language usable and asm.js will make it fast"). They are wrong, but they don't know it yet.

> The point is to use existing Fortran or C++ libraries or Lua code or whatever. The Unreal game engine is already already.

That's right. It's also different from the original scenario.

> Depending on how asm.js evolves and defines its own API standard (maybe concurrency model including C++11 stuff), this could change the browser and server world.

This is what we should be speaking about. Dart still needs to mature, which will slow it down, while JavaScript is already a mature(-ish) language and they can focus on adding the important features (generators in ES6, anyone?). Parallelism in Dart is still in its infancy, async is still hard, JS interop still feels heavy and kludgy. We need a killer selling point (productivity? Performance? True, but too abstract), but before we get to it, we need to work through the boring parts. In the meantime, JS people can easily surpass us.

LT

kc

unread,
May 19, 2013, 6:18:20 AM5/19/13
to mi...@dartlang.org
On Saturday, May 18, 2013 10:49:50 AM UTC+1, Ladislav Thon wrote:


To me, it looks like that for a lot of people, this is exactly the point ("ES6 will make the language usable and asm.js will make it fast"). They are wrong, but they don't know it yet.


Lars B's Google IO presentation was spot on - with a clean sane set of runtime semantics it's possible to build a fast, stable and simpler VM. And the language should reflect the semantics. And should be the natural partner for modern web apps - based on Web Components.
But for some reason it has been decided to beat the language with the Java/c# ugly stick - for the sake of familiarity.

The ES6 syntax (with TypeScript style ":" annotations) will actually be nice to code in. A subset will be optimizable - implementors will do this. Maybe not DartVM fast - but fast enough.

You seem to want to a new VM for serverside programming. You are spoilt for choice - Node, Java and JVM languages, Go, Rust, PHP etc.
Touch, mobile and graphics are the key - and a better VM is needed here. Not serverside - that's gravy.
The analyser, editor and even dart2js should take a backseat compared to the ARM VM on mobile.

You are wrong but don't know it yet.

K.

Ladislav Thon

unread,
May 19, 2013, 6:23:28 AM5/19/13
to mi...@dartlang.org
The ES6 syntax (with TypeScript style ":" annotations) will actually be nice to code in.

Yeah, when you forget today's JavaScript. The nice parts of ES6 are almost an entirely new language.
 
A subset will be optimizable - implementors will do this.

They are doing it already. The problem is that noone really knows how the subset looks like. If you hit the sweet spot, you are fine -- but it's very easy to get out of the borders without even realizing.

LT

kc

unread,
May 19, 2013, 7:57:51 AM5/19/13
to mi...@dartlang.org


On Sunday, May 19, 2013 11:23:28 AM UTC+1, Ladislav Thon wrote:

The ES6 syntax (with TypeScript style ":" annotations) will actually be nice to code in.

Yeah, when you forget today's JavaScript. The nice parts of ES6 are almost an entirely new language.

Exactly. And it's not bad. If ES6 goes ahead I will code to this subset. Using a Lint/Typescript pre-compiler to stick the 'good parts'.
 
 
A subset will be optimizable - implementors will do this.

They are doing it already. The problem is that noone really knows how the subset looks like. If you hit the sweet spot, you are fine -- but it's very easy to get out of the borders without even realizing.


Stick to classes, modules - the new stuff. Lint style tools will be able to keep you within the bounds.

I would like to 'bet against Javascript'. Dart in it's current form does not enable me to make that bet.

I honestly feel that my choosing the C style type syntax - following on form Java/C# - Dart is making a fundamental mistake.
It makes what are tool time type annotations seem like a fundamental part of the language. And is misleading.

Much better to have gone for:

// syntax which encourages:
// - types on signatures 
// - type inference for locals 
// - makes immutable bindings succinct and easy

myfunction(a:int, b:num, c:string) {
    val x = 4; // immutable binding  - typed to int
    var y = 4; // mutable binding - typed to int
    var z:int; // mutable binding - uninitialised - typed to int
}

K.


 

Alex Tatumizer

unread,
May 19, 2013, 1:02:38 PM5/19/13
to mi...@dartlang.org
>Good grief!  Poor Alice. Stuck translating one error prone legacy language to another error prone legacy language in > order to get some performance from her shiny new browser.

Plot thickens.
Turns out, Alice's uncle, Victor, former embedded programmer, has recently retired and moved up North where he spends his days fishing. Scared by horrors of C programming, Alice calls him and shares her grievances. Victor suddenly gets very excited: he sees the opportunity to get back to business, at the same time  saving his beloved niece from trouble. He sells all his fishing equipment and rushes to the rescue.





 

--

jim.trainor.kanata

unread,
May 19, 2013, 2:14:07 PM5/19/13
to mi...@dartlang.org
When Victor eventually clues in to how messed up web development really
is, and realizes that "asm.js" isn't actually a new cpu architecture but
a scripting language (and a scripting language that isn't even as good
as the Lisp he uses to customize his favorite editor - emacs), he'll
wander off muttering something about "kids these days..." and go back to
fishing.

Ahmet A. Akın

unread,
May 19, 2013, 2:16:03 PM5/19/13
to mi...@dartlang.org


On Saturday, May 18, 2013 2:32:25 AM UTC+3, Filipe Morgado wrote:
I believe that asm.js currently runs at roughly half the speed of native code (2x the time).

Optimized Dart code (typed_data) apparently beats Java, so we can expect something like 1.2x the processing time of native code.


According to my tests, only with SIMD it can beat java in some cases. Other typed_data lists are not yet as fast as Java. Overall performance still needs improvement.
 
I'd rather have the Dart team concentrate on the Dart VM than on some doubtful JS-subset cross-compilation.

I think both are equally important. Actually dart2js is more important in the short term. 

kc

unread,
May 28, 2013, 12:58:13 PM5/28/13
to mi...@dartlang.org
Interesting article on asm.js - which mentions Dart.

Could Dart use SIMD for the benchmarks Peter Bright used.

K.

kc

unread,
May 28, 2013, 12:59:16 PM5/28/13
to mi...@dartlang.org

Alex Tatumizer

unread,
May 28, 2013, 1:54:35 PM5/28/13
to mi...@dartlang.org
There's one extra consideration that gets omitted from asm.js benchmarks like the one above.
When function is worth writing in C, it's worth also being optimized in C.
So you spend some time to make it perform.

Then you translate it to asm.js, and there's no guarantee whatsoever that your optimizations are good after translation.
So probably you should optimize asm.js code, too (or *instead*) to get decent performance. This is the task not for the weak of heart. Actually, even this effort may be lost when you modify original C code.

Without this extra optimization, asm.js will probably perform *at best* just a bit better than java (slower than C by 2 times).
Don't forget that you have also normal javascript, and some glue should be used internally to create a coherent whole. Some performance will be lost.
In a word, I would expect performance of java.

Dart is getting close to performance of java. I did some experiments with rewriting/optimizing dart String methods in pure dart and compared with java.
We are very close. What is missing is typed arrays optimizations, StringBuffer optimizations and a couple of other things which are certainly doable.
Eventually, there's a good chance that in Chrome, pure dart will be faster than average asm.js. (Server-side dart can be at the level of java or better quite soon).
But cross-compilation to asm.js is an open problem.

*NOTE that java is very good in absolute terms, so being equal to it is a great achievement anyway, be it asm.js or dart or whoever. Java is still
equal or faster than go language, even after improvements in 1.1



Reply all
Reply to author
Forward
0 new messages