Search Unity

Periodic framerate spikes on iOS. I think the culprit may be RenderForwardOpaque.Render > Clear

Discussion in 'General Graphics' started by thatpixelguy, Feb 7, 2017.

  1. thatpixelguy

    thatpixelguy

    Joined:
    Jan 16, 2014
    Posts:
    3
    Hey all, first post here.

    I've been working on a 2D game in Unity for the past few years. Recently I started testing it on my iPhone 6S Plus, and I've been noticing periodic framerate spikes that happen every few seconds. They're minor, and not everyone who tests the game notices it -- however, the game is a difficult, fast-paced platformer that's designed for speedruns, so periodic performance hiccups during gameplay are unacceptable.

    First off, I don't think the culprit is the garbage collector. I'm using object pooling and I've used deep profiling on the desktop version to make sure I'm not generating a ton of garbage, and everything looks OK on that front.

    So I opened up the profiler while it was running on my iPhone to see if I could figure out what was going on. The only thing that jumps out at me is this:



    As shown in the screenshot, Render.OpaqueGeometry > RenderForwardOpaque.Render > Clear periodically spikes up to 10+ ms of CPU time (see the bright green spikes), which as far as I can tell appears to be enough to cause the framerate hiccups.

    I've tried to research this issue online but I haven't been able to find anything about what this actually does and what I could do to prevent it from spiking.

    Here's some background about my game which may/may not be helpful:

    I was originally developing it in Monogame, but for various reasons I ended up deciding to switch to Unity. Fortunately the bulk of my code was more or less engine-agnostic, so I was able to port it pretty quickly. As a result, it minimally uses the Unity API. The only scene in the project consists entirely of a camera with a bootstrap script that runs the rest of my C# code.

    This is relevant because of how I handle rendering. I wrote a basic sprite batching script: Each batch keeps arrays of vertices, triangles, UVs, etc. that are constantly updated by my game entities. In OnPostRender(), these arrays are assigned to the corresponding fields in the batch's Mesh object, which is then drawn using DrawMeshNow. (Note: the arrays are initialized at startup, and are not being allocated anew every frame). In order to achieve an accurate old-school look, I'm rendering the meshes to a texture first, and then scale up the texture and draw it in OnGUI() using Graphics.DrawTexture. (Another note: I tried rendering directly to the screen without drawing to the texture first, but I didn't notice any improvement in performance.)

    Again, let me reiterate that I am generating a very small amount of garbage in the game loop. The stuff I appear to be responsible for is about 80 bytes every frame, which is much less than what the profiler tells me Unity is generating every frame. I also manually run GC.Collect whenever the level reloads to hopefully prevent it from running during gameplay.

    More info: On average, I'm drawing about 600 vertices every frame. With the exception of backgrounds, all of my sprites are located on a single texture atlas. There are usually a total of 4 SetPass calls during gameplay.

    I've got the vsync/target framerate setup like this:

    QualitySettings.vSyncCount = 1;
    Application.targetFrameRate = 60;


    I've tried tweaking with the quality and graphics settings but haven't been able to spot any improvements.

    I'm running Unity 5.5.1p1, and I've been building the iOS version with the il2cpp option.

    I've been pretty much tearing my hair out over this but can't seem to make any progress. If anyone has any ideas or insight, it'd be greatly appreciated. If you need more info please let me know!
     
  2. thatpixelguy

    thatpixelguy

    Joined:
    Jan 16, 2014
    Posts:
    3
    Update:

    I rolled back to Unity 5.5.0f3, and the framerate issues magically went away, so it seems this issue was introduced in 5.5.1.

    In 5.5.0f3, the Render.OpaqueGeometry / RenderForwardOpaque.Render / Clear call does not spike at all during gameplay: (see bright green section)



    Unfortunately, I can't ship my game with 5.5.0f3 because the splash screens were bugged on iOS in that release. I'm going to try installing 5.4.4f1 to see if I get acceptable performance, but I'd really like to ship with 5.5 because the new splash screens are awesome.
     
  3. dev_alleylabs

    dev_alleylabs

    Joined:
    Sep 30, 2015
    Posts:
    2
    Hi, how everything going? I'm facing the same problem. Any luck with 5.4.4f1?
     
  4. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,526
    Did you send a bug report? it may help to make unity aware