Search Unity

Disappointing End-to-End Latency in Unity

Discussion in 'Editor & General Support' started by GuruRamen, Oct 28, 2016.

  1. GuruRamen

    GuruRamen

    Joined:
    Jan 15, 2014
    Posts:
    13
    I'm working on an application that needs very low input to photon latency (not VR), so I've been doing some careful measurements of the time between a physical input and the time that a response to that input can be seen.

    The results for the Unity version of this test app are disappointing and in some ways surprising, so I thought I'd post my results here to see if anyone (especially Unity Devs) might have some insight, and maybe some suggestions on how to improve the result.

    The details of the test are as follows:
    1. I made a very simple USB HID Generic peripheral, polled at 1Khz, that simply returns the state of an attached button.
    2. I write the simplest possible app that reads from that device and changes the entire screen from black to white when a button press is read.
    3. I trigger an oscilloscope when the button is pressed and then measure the time from the button press to when signal level on a VGA line changes. (Obviously this excludes lag in the display.)
    4. All tests are run on the current version of Ubuntu on a older desktop PC with a GT630 GPU and the latest binary drivers.

    The table below shows the results for my Unity app at various resolutions (selected in the startup dialog) and with Vsync enabled/disabled.

    upload_2016-10-28_10-59-32.png

    For comparison, the corresponding test written in C/GLUT, and running under the same configuration, has a minimum latency of 4 milliseconds with vysnc disabled and 8 with vsync enabled.

    Of course, where Vsync is disabled, the start of the signal change won't correspond with the top of the sync and tearing is seen.

    So, some questions:
    1. Why is Unity doing so much worse than raw GL?
    2. What's with the 100 msec penalty with vsync enabled?
    3. Why is the non-vysnc case so resolution-dependent? Presumably rendering a single polygon (?) should take essentially zero time on a modern-ish GPU.
    4. Is there a way to improve the results on Unity?
    (Unity source posted below. Note that the scene is just a single cube with the camera positioned such that the cube's front surface fills the screen. The script below is attached to the cube.)

    Thanks in advance,
    Dan


    Code (CSharp):
    1.    
    2. public class HidLatencyTest : MonoBehaviour
    3. {
    4.     public Texture2D WhiteTexture;
    5.     public Texture2D BlackTexture;
    6.  
    7.     [DllImport("HidLib.so")]
    8.     private static extern int HidOpen();
    9.  
    10.     [DllImport("HidLib.so")]
    11.     private static extern int HidRecv();
    12.  
    13.     void Start()
    14.     {
    15.         QualitySettings.vSyncCount = 0;
    16.         HidOpen();
    17.     }
    18.  
    19.     void Update()
    20.     {
    21.         int hidVal = HidRecv();
    22.  
    23.         if (hidVal == 1) {
    24.             GetComponent<Renderer>().material.mainTexture = WhiteTexture;
    25.         } else {
    26.             GetComponent<Renderer>().material.mainTexture = BlackTexture;
    27.         }
    28.  
    29. }
    30.  


     
  2. GuruRamen

    GuruRamen

    Joined:
    Jan 15, 2014
    Posts:
    13
    (Bump)

    Any thoughts at all? I'm a bit surprised that other folks aren't running into this issue, especially when doing VR work where even a few milliseconds of latency really matter, and where 100+ msec would be around 5x the target max.

    Or maybe it's only a Linux thing?

    Thanks,
    Dan
     
  3. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    It's not really an apples-to-apples test is it?. OpenGL is an API relatively close to the hardware. Unity is an engine, some of it multithreaded behind the scenes with rendering job queues and such, fairly complex lighiting shaders, shadows, and so on.

    You might try some experiments using the GL class. I don't know if this skips any of the pipeline and does direct GL calls or not, but it's worth a try to see if you get different numbers.

    Regardless, when you add levels of abstraction to the graphics API you're going to get some latency.
     
    DroidifyDevs likes this.
  4. GuruRamen

    GuruRamen

    Joined:
    Jan 15, 2014
    Posts:
    13
    Hey Dave,

    I suppose it is slightly apples to oranges, but still 10 or 20 msec still seems like a ton of overhead nowadays when people are targeting < 25 msec motion to photon in VR, and counting ever millisecond of monitor lag.

    FWIW, it did a roughly comparable test in Cocos2d-x; flipping a single full-screen sprite on when the button was pressed. With Vysnc disabled the latency ranged from 7-9 milliseconds on the same HW, OS, etc.

    In any event, thanks.

    Dan