New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 5 users
Status: Duplicate
Merged: issue v8:2527
Owner: ----
Closed: Feb 2013
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 1
Type: Compat



Sign in to add a comment
Canvas performance degrades significantly after 10 seconds
Project Member Reported by agektmr@chromium.org, Feb 4 2013 Back to list
Version: Chrome Beta 25.0.1364.64
OS: Android 4.2 Nexus7

1. Open Chrome for Android Beta on Nexus 7
2. go http://mofmof-js.googlecode.com/svn/trunk/test/showcase/particle/30000.htm
3. Click either setTimeout, setInterval, setImmediate or requestAnimationFrame button
4. See how particles flow for 10 seconds

notice that at some point, speed of particles' flow slows down significantly

Here's the comparison chart (in Japanese)
http://uupaa.hatenablog.com/entry/2012/02/08/160039
 
Cc: senorblanco@chromium.org bsalomon@chromium.org skyos...@chromium.org
Not sure this is explicitly a GPU / canvas issue. I'm seeing a huge spike in terms of GC events in Chrome for Android Beta on a Galaxy Nexus.
Screen Shot 2013-02-04 at 10.51.33 AM.png
105 KB View Download
Comment 3 by yu...@chromium.org, Feb 4 2013
Cc: loislo@chromium.org yu...@chromium.org
I spent some time playing with the demo. Before I explain what I've found let me explain the structure of the demo. There is a single 'tick' function which runs via setTimeout, setInterval, requestAnimationFrame, setImmediate. These control what triggers th call to 'tick' but 'tick' is where all the work is.

Tick consists of these phases:

Update to canvas pixel data
Updates to particle data and pixel data [1]
Putting pixel data onto a canvas
Updating the FPS counter display

I downloaded the demo and commented out different sections of the tick function to narrow down the cause of the GC's. The GC's only happen when the following code [1] runs:

    for (i = 0, iz = particle.length; i < iz; i += 4) {
        x  = particle[i    ];
        y  = particle[i + 1];
        vx = particle[i + 2];
        vy = particle[i + 3];
        dx = mx - (x | 0);
        dy = my - (y | 0);
        dd = dx * dx + dy * dy;
        if (!dd) { // [avoid] division by zero
            dd = 1;
        }
        acc = 50 / dd;
        vx += acc * dx;
        vy += acc * dy;
        x  += vx;
        y  += vy;
        x = x > width  ? 0 : x < 0 ? width  - 1 : x;
        y = y > height ? 0 : y < 0 ? height - 1 : y;

        particle[i    ] = x;
        particle[i + 1] = y;
        particle[i + 2] = vx * 0.96;
        particle[i + 3] = vy * 0.96;

// 【最適化】紫のドットを打つ, alpha=200 は適当
        j = ((x | 0) + (y | 0) * width) * 4;
        data[j] = 230;
        data[j + 2] = 230;
        data[j + 3] = 200;
    }

As a guess, this function is creating many number instances which immediately become garbage. The number instances exhaust the young heap, forcing a scavenge (young heap GC) pass. The scavenge frees lots of memory and doesn't trigger a full GC. Because the objects immediately become garbage they are not findable via DevTools Heap Profile because they are never reachable.

What I'm still wondering about is why so much garbage is being generated by that loop.
Cc: jkummerow@chromium.org
Status: Available
I'm running the full version (the above one doesn't have the conditional branch with the fps counter) and the "tick" function gets deoptimized after a new object is explicitly allocated - this seems to be the new Date().

If I remove that branch with the fps indicator, I get no GC issues whatsoever.

We are investigating though why that conditional branch keeps confusing V8 even after the fist visit.

The performance drop after 10 seconds is due to V8 not collecting type feedback for unary additions, and therefore after some time giving up trying to optimize the function tick().

Workaround: remove the "+" from the line "var now = +new Date;". The rest of the demo does not need to be modified -- JavaScript Date objects can be subtracted from each other without manual coercion to numbers. If you insist on doing the coercion manually, do a multiplication with 1 instead of the unary plus.

I've filed https://code.google.com/p/v8/issues/detail?id=2527 for fixing this in V8, but would consider it fairly low priority because the workaround is so easy.

I'm leaving this bug open in case there are other issues that warrant investigation; feel free to close it if removing the "+" solves all problems :-)
Mergedinto: v8:2527
Status: Duplicate
Project Member Comment 8 by bugdroid1@chromium.org, Mar 10 2013
Labels: -Type-Bug -Area-Compat -Feature-GPU Type-Compat Cr-Internals-GPU
Sign in to add a comment