When threads_a_gogo beats node 2 to 1

365 views
Skip to first unread message

Jorge

unread,
Apr 12, 2012, 6:46:02 AM4/12/12
to nod...@googlegroups.com
<https://gist.github.com/2362548>

$ node bench.js
Threads_a_gogo JS thread -> 4624 (ms) 298607040
Node's main JS thread -> 8471 (ms) 298607040
Ratio: 1.83 times faster

(Sorry, I couldn't resist the temptation)

:-P
--
Jorge.

billywhizz

unread,
Apr 12, 2012, 8:57:03 AM4/12/12
to nod...@googlegroups.com
are we just seeing the benefit of using 2 cores instead of 1? would be nice to also have the native node.js script in order to be able to run the benchmark...

Jorge

unread,
Apr 12, 2012, 9:39:54 AM4/12/12
to nod...@googlegroups.com
On Apr 12, 2012, at 2:57 PM, billywhizz wrote:

> are we just seeing the benefit of using 2 cores instead of 1?

No no no, not at all. You're seeing the same piece of JavaScript code running in node's main JavaScript thread vs running it in a thread_a_gogo. Nothing is going on in parallel here, it's simply either one thread or the other.

> would be nice to also have the native node.js script in order to be able to run the benchmark...

Parse error... ?
--
Jorge.

Tim Caswell

unread,
Apr 12, 2012, 9:54:16 AM4/12/12
to nod...@googlegroups.com
What makes the main thread so slow in comparison?  It's the same v8 right?

--
Jorge.

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

mscdex

unread,
Apr 12, 2012, 1:29:00 PM4/12/12
to nodejs
On Apr 12, 9:54 am, Tim Caswell <t...@creationix.com> wrote:
> What makes the main thread so slow in comparison?  It's the same v8 right?

Here's something more interesting:

https://gist.github.com/2369318

Threads_a_gogo JS thread -> 3039 (ms) 298607040
Node's main JS thread -> 4677 (ms) 298607040
Ratio: 1.54 times faster than main JS thread
New, separate VM -> 3065 (ms) 298607040
Ratio: 1.01 times faster than new VM

mscdex

unread,
Apr 12, 2012, 1:32:44 PM4/12/12
to nodejs
On Apr 12, 1:29 pm, mscdex <msc...@gmail.com> wrote:
> https://gist.github.com/2369318
>
> Threads_a_gogo JS thread ->  3039 (ms)  298607040
> Node's main JS thread    ->  4677 (ms)  298607040
> Ratio: 1.54 times faster than main JS thread
> New, separate VM ->  3065 (ms)  298607040
> Ratio: 1.01 times faster than new VM

Also, occasionally the new VM will be faster than the threads_a_gogo
execution.

Tim Caswell

unread,
Apr 12, 2012, 2:56:29 PM4/12/12
to nod...@googlegroups.com
Ahh, it's the eval and not having closures and global scope.  I'll bet that's why it's faster, because it's in a clean environment.  Try the same with new Function() instead of eval locally.

Vyacheslav Egorov

unread,
Apr 13, 2012, 8:48:51 AM4/13/12
to nod...@googlegroups.com
fib in "Node's main JS thread" case is a "local" function declaration, V8 compiles recursive call as 

t32  LoadContextSlot t5[8]
t39  CallFunction t5 t32 #2 changes[*]

in "threads..." and "separate VM" (which is actually not a separate VM, name is misleading) case it's a global function and recursive invocation looks like:

t36  LoadGlobalCell [0x2c37c320b761]
t37  CheckFunction t36 0x1a9cbc67f2a9
t41  CallKnownGlobal o #2 changes[*]

if you look at assembly you'll see that call-known-global is actually much simpler and direct (and thus faster) than call-function which uses separate generic stub:

                  ;;; @40: call-known-global.
0x3c5d7c2c30d   109  48bff96d452dc6150000 REX.W movq rdi,0x15c62d456df9    ;; object: 0x15c62d456df9 <JS Function fib>
0x3c5d7c2c317   119  4c89e1         REX.W movq rcx,r12
0x3c5d7c2c31a   122  e881ffffff     call 0  (0x3c5d7c2c2a0)    ;; debug: position 41
                                                             ;; code: OPTIMIZED_FUNCTION

vs.

                  ;;; @52: call-function.
0x1e5a9c3a52fd   125  e85e46f6ff     call 0x1e5a9c309960     ;; debug: position 139
                                                             ;; code: STUB, CallFunctionStub, argc = 1

[call function stub is a complicated generic stub that can handle all kinds of calls]

--
Vyacheslav Egorov

Bert Belder

unread,
Apr 13, 2012, 10:45:02 AM4/13/12
to nodejs
On Apr 13, 2:48 pm, Vyacheslav Egorov <vego...@chromium.org> wrote:
> fib in "Node's main JS thread" case is a "local" function declaration, V8
> compiles recursive call as
Thanks for your analysis, Vyacheslav.

So what can we do about it? It seems that in node all functions will
be "local" functions because of the module system. Is it not possible
to have an efficient stub for these guys?

- Bert

Vyacheslav Egorov

unread,
Apr 13, 2012, 11:19:41 AM4/13/12
to nod...@googlegroups.com
No, it is definitely possible. It requires a simple analysis at the parser level and minor changes in Crankshaft pipeline.
 

--
Vyacheslav Egorov

Vyacheslav Egorov

unread,
Apr 13, 2012, 12:21:29 PM4/13/12
to nod...@googlegroups.com
To ensure that this is not going to fall through, I have filed an issue:

http://code.google.com/p/v8/issues/detail?id=2079

--
Vyacheslav Egorov

Jorge

unread,
Apr 13, 2012, 1:06:02 PM4/13/12
to nod...@googlegroups.com
On Apr 13, 2012, at 4:45 PM, Bert Belder wrote:
>
>
> Thanks for your analysis, Vyacheslav.
>
> So what can we do about it? It seems that in node all functions will
> be "local" functions because of the module system. Is it not possible
> to have an efficient stub for these guys?

Yes, thanks for your analysis, Vyacheslav. A fix for that would be über awesome as it would all of a sudden make node almost 2x faster. And the whole node community would then owe you many, many Ks of beers!
--
Jorge.

Mark Hahn

unread,
Apr 13, 2012, 2:49:08 PM4/13/12
to nod...@googlegroups.com
, many Ks of beers! 

Is that Kilograms or Kegs?

Dan MacTough

unread,
Apr 13, 2012, 3:09:23 PM4/13/12
to nod...@googlegroups.com
Many thousands!

Jorge

unread,
Apr 13, 2012, 4:46:37 PM4/13/12
to nod...@googlegroups.com
On Apr 13, 2012, at 8:49 PM, Mark Hahn wrote:

> > , many Ks of beers!
>
> Is that Kilograms or Kegs?

Thousands :-P
--
Jorge.

Vyacheslav Egorov

unread,
Apr 19, 2012, 11:15:29 AM4/19/12
to nod...@googlegroups.com
We have fixed the issue. You can try again with newest V8 from the
bleeding_edge branch.

--
Vyacheslav Egorov

Jorge

unread,
Apr 19, 2012, 2:32:15 PM4/19/12
to nod...@googlegroups.com
Looks promising, now this simple test <https://gist.github.com/1511972> loops ~ 3 times faster!

****** BEFORE:

$ node -e 'console.log(process.versions)'
{ node: '0.7.5',
v8: '3.9.5',
ares: '1.7.5-DEV',
uv: '0.6',
openssl: '0.9.8r' }

$ node Desktop/nextTick.js
loopsPerSecond: 103412616.3, nextTicksPerSecond: 671885.8, ratio: 153.9x times faster
loopsPerSecond: 104602510.5, nextTicksPerSecond: 662346.2, ratio: 157.9x times faster
loopsPerSecond: 114025085.5, nextTicksPerSecond: 658962.3, ratio: 173.0x times faster
loopsPerSecond: 114155251.1, nextTicksPerSecond: 653162.1, ratio: 174.8x times faster
loopsPerSecond: 112233445.6, nextTicksPerSecond: 655562.1, ratio: 171.2x times faster

****** AFTER:

$ node -e 'console.log(process.versions)'
{ node: '0.7.5',
v8: '3.10.5 (candidate)',
ares: '1.7.5-DEV',
uv: '0.6',
openssl: '0.9.8r' }

$ node Desktop/nextTick.js
loopsPerSecond: 353356890.5, nextTicksPerSecond: 750116.9, ratio: 471.1x times faster
loopsPerSecond: 312500000.0, nextTicksPerSecond: 749467.4, ratio: 417.0x times faster
loopsPerSecond: 311526479.8, nextTicksPerSecond: 754602.5, ratio: 412.8x times faster
loopsPerSecond: 313479623.8, nextTicksPerSecond: 747679.7, ratio: 419.3x times faster
loopsPerSecond: 313479623.8, nextTicksPerSecond: 751938.1, ratio: 416.9x times faster

And this <https://gist.github.com/2369318> :

****** BEFORE:

$ node -e 'console.log(process.versions)'
{ node: '0.7.5',
v8: '3.9.5',
ares: '1.7.5-DEV',
uv: '0.6',
openssl: '0.9.8r' }

$ node bench.js
Threads_a_gogo JS thread -> 4712 (ms) 298607040
Node's main JS thread -> 7915 (ms) 298607040
Ratio: 1.68 times faster than main JS thread
New, separate VM -> 4751 (ms) 298607040


Ratio: 1.01 times faster than new VM

****** AFTER:

$ node -e 'console.log(process.versions)'
{ node: '0.7.5',
v8: '3.10.5 (candidate)',
ares: '1.7.5-DEV',
uv: '0.6',
openssl: '0.9.8r' }

$ node bench.js
Threads_a_gogo JS thread -> 4954 (ms) 298607040
Node's main JS thread -> 4794 (ms) 298607040
Ratio: 0.97 times faster than main JS thread
New, separate VM -> 4935 (ms) 298607040
Ratio: 1.00 times faster than new VM

Somehow, now you've broken my threads !
--
Jorge.

Reply all
Reply to author
Forward
0 new messages