Status

()

defect
RESOLVED DUPLICATE of bug 772892
7 years ago
7 years ago

People

(Reporter: michael, Unassigned)

Tracking

9 Branch
x86
macOS
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

7 years ago
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:9.0.1) Gecko/20100101 Firefox/9.0.1
Build ID: 20111220165912

Steps to reproduce:

I tested the performance of Math.pow


Actual results:

Math.pow slowed precipitously when I upgraded to Firefox 9.


Expected results:

It should've gotten faster or stayed the same.
Assignee: nobody → general
Component: General → JavaScript Engine
Product: Firefox → Core
QA Contact: general → general
Looks like Math.pow() is 10x or so faster under TM than under JM+TI.  We used to use a traceable native here; are we ending up with a stubcall now and losing or something?
Status: UNCONFIRMED → NEW
Ever confirmed: true
dvander, will IM have a sane way of making this not suck?

Note that inlining POW (which is what V8 does) is a huge pain and hellhole of complexity.
Ah, I see where the 10x thing comes from.  It's just due to the benchmark being bogus.  The real difference is order of 40% faster Math.pow in TM compared to JM+TI.

But TM (or more precisely nanojit) knows that Math.pow is a pure function, and will dead-code-eliminate it when the return value is not actually used for anything, as in this benchmark.
Note that the 40% slowdown is real; the original use-case from the stackoverflow thread actually used the return value of Math.pow for something and did get slowed down.
(In reply to Boris Zbarsky (:bz) from comment #3)
> dvander, will IM have a sane way of making this not suck?
> 
> Note that inlining POW (which is what V8 does) is a huge pain and hellhole
> of complexity.

v8 doesn't inline Math.pow but it does look like they compile a hand-optimized version and call out to it. But yeah, it should be easy to do either what CS or TM do and either way we can eliminate calls to known-pure functions.
What if we use a MathCache for Math.pow?
Math.pow takes two arguments; MathCache handles keying off a single double, right?
(In reply to Boris Zbarsky (:bz) from comment #8)
> Math.pow takes two arguments; MathCache handles keying off a single double,
> right?

Right! So, can't we extend the MathCache class (or better create another class) to support also math functions with two arguments? It's just an idea, I don't know if this would improve performance.
If you think it's worth trying, I can do this.
You can try, but I suspect the cost here is the actual call, not the pow() operation itself.  Still, worth checking.
> var t0 = new Date;
> for (var i=0; i<10000000; i++) {
>   Math.pow(10.5,10.6);
> }
> print(new Date - t0);

On a test like this, a BinaryMathCache would improve a bit the performance.
Without the cache ~1263, with the cache ~302.
When the arguments of the pow are integers, the gap is a lot smaller (because powi is used instead of pow).
Also something like this would give a performance benefit (less that a binarymathcache and with a little difference in precision):
> MathCache *mathCache = GetMathCache(cx);
> if (!mathCache)
>   return JS_FALSE;
> z = mathCache->lookup(log, x);
> z = mathCache->lookup(exp, y*z);
However also without the cache, exp(y*log(x)) seems to be a bit faster than pow(x,y).
IonMonkey optimizes this like TM, a specialized native is called for Math.pow(double, double) or Math.pow(double, int), and we can fold/hoist/DCE these etc. Marking as duplicate of that bug.
Status: NEW → RESOLVED
Last Resolved: 7 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 772892
You need to log in before you can comment on or make changes to this bug.