Search Unity

FrameTimingManager.GetLatestTimings always returning 0 timings.

Discussion in 'Scripting' started by Q-Ted, Aug 8, 2018.

  1. Q-Ted

    Q-Ted

    Joined:
    Dec 16, 2016
    Posts:
    46
    Hello,

    I am trying to make use of the FrameTimingManager, but GetLatestTimings always seems to return 0 timings.

    This is what I am currently doing while trying to see if it works:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using TMPro;
    5. using System.Text;
    6.  
    7. public class FrameTimeDisplay : MonoBehaviour
    8. {
    9.     public TMP_Text textElement = null;
    10.     private FrameTiming[] m_frameTimings = new FrameTiming[8];
    11.     private StringBuilder m_stringBuilder = new StringBuilder(32);
    12.  
    13.     private void Update()
    14.     {
    15.         uint capturedAmount = FrameTimingManager.GetLatestTimings(8, m_frameTimings);
    16.  
    17.         m_stringBuilder.Length = 0;
    18.         if (capturedAmount > 0)
    19.         {
    20.             // Do some calculations here...
    21.            
    22.             // Debug display...
    23.             m_stringBuilder.Append("CPU: ");
    24.             m_stringBuilder.Append(m_frameTimings[0].cpuFrameTime);
    25.             m_stringBuilder.Append("ms\n");
    26.             m_stringBuilder.Append("GPU: ");
    27.             m_stringBuilder.Append(m_frameTimings[0].gpuFrameTime);
    28.             m_stringBuilder.Append("ms");
    29.         }
    30.         textElement.SetText(m_stringBuilder);
    31.  
    32.         FrameTimingManager.CaptureFrameTimings();
    33.     }
    34. }
    35.  
    The Unity version I am using is 2018.1.4f1. Windows editor & standalone.
    Am I doing something wrong here or does my system not support it?
     
    Last edited: Aug 8, 2018
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Dragnipurake97, jashan and Q-Ted like this.
  3. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Actually, while this posting has a nice explanation, which is also much more helpful than the API documentation of those methods (thank you @timothyh_unity), it's not quite clear to me how exactly this works. Examples in the documentation would really help - and also, a clear statement on which platforms this can be used on now.

    I tried code similar to what @Q-Ted posted, assuming that when I call FrameTimingManager.CaptureFrameTimings() at the end of the Update-method, it should then have data until the next call into Update(). But in the documentation, it says only "complete frames" are captured, and that could mean that when I call it between two updates, if the GPU is still busy rendering and that would explain I'm never getting frame timings.

    By now, I have tried a variety of different approaches, including calling it directly before GetLatestTimings(), and also calling CaptureFrameTimings() in one frame, then GetLatestTimings() the next, then Capture again and so forth.

    It does kind of look like maybe, this is still only Xbox One ... but if that really is the case, it should absolutely say so in the API documentation.

    I'd love to get those CPU frame timings - but apparently, for now, it seems I'll have to go with XRStats (which only tells me about GPU time).

    Btw, I'm on 2018.3.0b12. I could move to 2019.1.0alpha if that would help (and when Visual Effects Graph will work there, too ;-) ).
     
    futurlab_xbox likes this.
  4. WayneLJ

    WayneLJ

    Joined:
    Aug 6, 2015
    Posts:
    12
  5. CGDever

    CGDever

    Joined:
    Dec 17, 2014
    Posts:
    156
    The same weird case. I call everything once per frame:
    rameTimingManager.CaptureFrameTimings ();
    // uint Returns the number of FrameTimings it actually was able to get
    allowedFrameTimings = FrameTimingManager.GetLatestTimings ( kNumFrameTimings, frameTimings );
    if (frameTimings.Length < kNumFrameTimings) {
    Debug.LogFormat ( "Skipping frame {0}, didn't get enough frame timings.", m_frameCount );
    return;
    }
    m_gpuFrameTime = (double)frameTimings[0].gpuFrameTime;
    m_cpuFrameTime = (double)frameTimings[0].cpuFrameTime;

    But everything is 0 on OSX Unity 2019.2.9f1 :/
     
  6. relativegames

    relativegames

    Joined:
    Nov 22, 2013
    Posts:
    32
    Everything is 0 on 2019.2.19 and Unity 2020.1.0a22 too :|
     
    Last edited: Feb 12, 2020
  7. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    It works on XBox One only.
    Based on past experiences, "coming soon" in this context can be interpreted as ~5 years. I wouldn't expect this to be available earlier than Unity 2022, and there's a significant chance it won't be ever implemented.
     
    pimei and Dragnipurake97 like this.
  8. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    221
    It should actually work on almost all platforms now (Feb. 2020) - but I'm getting 0 too no matter what I do. I can make it scale (if I change to DirectX 12 only), but I see no performance improvement (might be due to my particles is CPU bound) however, something is still wrong as I get 0 for both "gpuFrameTime" and "cpuFrameTime".

    https://docs.unity3d.com/Manual/DynamicResolution.html

    "Unity supports dynamic resolution on Xbox One, PS4, Nintendo Switch, iOS , macOS and tvOS (Metal only), Android (Vulkan only), Windows Standalone and UWP (DirectX 12 only)."
     
  9. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    As for what I understand from that page, "DynamicResolution" refers to DynamicallyScalable, allowDynamicResolution and ScalableBufferManager. That's what works in most platforms. Only the included example makes use of FrameTimingManager, but that doesn't make it part of the Dynamic Resolution feature itself.

    From:
    https://docs.unity3d.com/ScriptReference/FrameTimingManager.html

    "If the platform does not support returning this value it will return 0."
     
  10. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    221
    I see what you mean, but it's a pretty S***ty move Unity to write all these systems are supported and then on the same page provide a code sample that only works on Xbox One :D

    When that said (and I already wrote that feedback to Unity) that code sample doesn't do as it indicates. "DetermineResolution()" does not at all "determine" any resolution...it writes a Debug.Log..that's it. And on that note, even when my frame froze for seconds, that Debug.Log wasn't fired, so that part doesn't work either.
    Anyway, even if it worked the code doesn't do what it indicates with that method name.

    And in relation to:
    "If the platform does not support returning this value it will return 0."

    It would be nice with some indication of what "platforms wasn't supported". When they put it like that, it's the same as saying "If it works it works, if not, good luck!" :)
     
    djarcas and fct509 like this.
  11. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Truly honestly, I wouldn't be surprised. Unity is now so big and has so many teams scattered around so many departments, that (IMHO) is perfectly possible that the guy who wrote the example for the docs had no connection at all with the guy/team developing the FrameTimeManager class. Or even if he had so, he may have been told the same "more platforms coming soon" reply.

    I wouldn't be surprised either! xD
     
  12. AndrewCzarnietzki

    AndrewCzarnietzki

    Joined:
    Jul 23, 2013
    Posts:
    189
    The documentation here is so bad that it made me log in and post a response :)

    The example doesn't actually do anything--it just returns a log. Somewhat useful for trying to figure out how the API works, but confusing. Aaaaaand, I get 0 as well, with no sense on what / when this works. DynamicResolution works like a charm, but this frame timing idea (which would be really useful) doesn't seem implemented?

    Has anyone here managed to get this to work?
     
    jashan likes this.
  13. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Personally I don't think this will be ever implemented further. It looks like this feature was abandoned years ago. I don't think they will continue with this given the new APIs / RP / DOTS / etc stuff they're focusing on. If all, they'll deprecate it and tell they're working in something else much better (tm) that might land in preview-alpha-experimental at some time within the next two years (tm).
     
    Last edited: Aug 20, 2020
    jashan likes this.
  14. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    ... and then be deprecated right before they actually get it into a state of being useful, replaced with something that does almost exactly the same but isn't quite compatible with the previous approach. Rinse. Repeat.

    Valve? Valve? CanIHazSource2PrettyPlease?
     
    fct509 and Edy like this.
  15. FrankBuss

    FrankBuss

    Joined:
    Dec 22, 2014
    Posts:
    55
    See here:
    https://stackoverflow.com/questions...t-usage-of-frametiming-and-frametimingmanager
    FrameTimingManager is not supported for Windows. And looks like the smart programmers at Unity decided to just return 0 instead of printing a log message that it is not supported, throwing an exception, or at least documenting this fact at https://docs.unity3d.com/ScriptReference/FrameTimingManager.html .

    Quick and dirty solution which shows at least the FPS, updated once per second:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class FPS : MonoBehaviour
    4. {
    5.     private float _fpsUpdate;
    6.     private float _lastFps;
    7.  
    8.     public void OnGUI()
    9.     {
    10.         _fpsUpdate += Time.deltaTime;
    11.         if (_fpsUpdate > 1)
    12.         {
    13.             _lastFps = 1.0f / Time.deltaTime;
    14.             _fpsUpdate = 0;
    15.         }
    16.         int w = Screen.width, h = Screen.height;
    17.         GUIStyle style = new GUIStyle();
    18.         Rect rect = new Rect(w / 10 * 9, 0, w / 10, h * 3 / 100);
    19.         style.alignment = TextAnchor.UpperRight;
    20.         style.fontSize = h * 3 / 100;
    21.         style.normal.textColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
    22.         GUI.backgroundColor = Color.black;
    23.         string text = string.Format("{0:0.} fps", _lastFps);
    24.         GUI.Box(rect, text);
    25.     }
    26. }
    27.  
    Just drop the script on an empty GameObject. Looks like this:

    fps.png
    But would be much better to have the exact numbers for the GPU and CPU times., as the Stats window in the editor can do it.
     
  16. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Tbh, while useful in general, an FPS-counter is nothing like getting info on how much time is spent on the GPU / CPU.

    For VR (where this is extremely important), you can at least use XRStats.TryGetGPUTimeLastFrame(...) to get the GPU frame time. Unfortunately, there is no equivalent for measuring the CPU time, so this is really only helpful if you're GPU bound (on the other hand, being GPU can often be handled by simply reducing the render resolution - with CPU issues, there's nothing that straightforward).

    I actually don't mind them returning 0: Getting exceptions for something like tracking performance statistics that could pop up depending on where the game is installed sounds like a recipe for disaster. Here's some code I use with the XRStats fallback (this will only work for VR projects, and only on certain VR SDKs, and consider is "pseudocode" because it refers to other stuff in my performance tracking class - but it should get you started):

    Code (CSharp):
    1.     private void CalculateFrameTimes() {
    2.         uint frameCount = FrameTimingManager.GetLatestTimings((uint)frameTimings.Length, frameTimings);
    3.         if (frameCount < 1) {
    4.             CalculateFrameTimesXRStats();
    5.         } else {
    6.             ProcessFrameTimeGpu(frameTimings[0].gpuFrameTime);
    7.             ProcessFrameTimeCpu(frameTimings[0].cpuFrameTime);
    8.         }
    9.  
    10.         totalFrameTimeGpu += lastFrameTimeGpu;
    11.         totalFrameTimeCpu += lastFrameTimeCpu;
    12.      
    13.         FrameTimingManager.CaptureFrameTimings();
    14.     }
    15.  
    16.     private void CalculateFrameTimesXRStats() {
    17.         if (XRStats.TryGetGPUTimeLastFrame(out float lastFrameTime)) {
    18.             ProcessFrameTimeGpu(lastFrameTime);
    19.         }
    20.     }
    21.  
    The methods ProcessFrameTimeGpu() and ProcessFrameTimeCpu() do stuff like calculating the min/max, count frames over certain thresholds and so forth. Obviously, totalFrameTimeGpu and totalFrameTimeCpu are used to calculate the average frame times.

    OpenVR has a method IVRCompositor::GetFrameTiming which delivers a lot of useful data in Compositor_FrameTiming. This is used for adaptive quality in ValveCamera, which was part of Valve's The Lab Renderer.
     
    rmon222 and ruudvangaal like this.
  17. james_cg

    james_cg

    Joined:
    Nov 13, 2019
    Posts:
    17
    So, this is unity. Fool developers every now and then.
    A simple interface to access cpu & gpu time would be great help for mobile game developers, but they would not offer it.
     
    jashan likes this.
  18. fct509

    fct509

    Joined:
    Aug 15, 2018
    Posts:
    108
    How does FrameTimingManager.getLatestTimings(...), not work on the Windows platform? It makes zero f*****g sense. At the very least, it should work from within the Unity Editor, because that's the one thing that is going to get used by all Unity developers. That one tool that all Unity developers use, and Unity didn't think, "We should make it work on that one thing that all of our clients use; you know that one tool that the company is named after."!

    Maybe my reaction is a bit extreme--I just spent the last three hours adding code that is supposed to record the gpu frame render times in an automated data capture project, only to find out that the API I built said code on doesn't f*****g work when you run it on a Windows Machine. I would have understood if it didn't work on certain mobile devices, but this should work on anything and everything that Unity's Profiler tool works on. There's no f****g way that Unity can say they can't grab said information when their own Profiler tool is able to grab said information.

    Anyways, I'm going to have to find a different way to get this data because I really don't want to tell my client, "Learn to use the Unity Profiler.".
     
  19. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,453
    I understand the frustrations but I'd still prefer if we could keep the forums in a more even keeled and professional tone.

    There are several long and complicated responses to why this is the current status of it but the short of it is: GPU profiling support is rather spotty right now and we're actively working on fixing that. This is happening with a focus on getting GPU timings to the Profiler's Recorder and ProfilerRecorder APIs as well as FrameTimingManager first, and then into the Profiler UI. Btw, as of 2020.1 Recorder can already get you GPU timings where the profiler UI can too, but only on Development builds. The newer ProfilerRecorder API allows us to also expose some of the stats in Release.
     
    Last edited: Dec 10, 2020
    jashan likes this.
  20. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,453
    Also, we are looking at updating the docs to be clearer about what is supported and what isn't but given the upcoming holiday season, getting all the details for that is going a bit slower than ideal and we'll likely not have an update before January.
     
    fct509 and Q-Ted like this.
  21. Q-Ted

    Q-Ted

    Joined:
    Dec 16, 2016
    Posts:
    46
    Thank you for the response @MartinTilo!

    I figured as much as the Unity profiler also isn't always able to profile the GPU on certain on-device builds when attached, but it's quite surprising it does/did not work in the editor. The documentation being clear on whether or not certain classes/features are available would be very nice and would save people some frustration!

    Hope you will be able to have a nice holiday season!
     
    fct509 and MartinTilo like this.
  22. CGDever

    CGDever

    Joined:
    Dec 17, 2014
    Posts:
    156
    Unity Community has a car (ScreenResolution technology) but still no engine (the timing system). So, we can’t drive the car, and instead are forced to push it along like a cart. Please don’t torture us any longer!

    An error message or even "-1" (worst case scenario, if it’s impossible to show an error message) would be much better than just "0".
    I have Unity 2020.2.2f1, and frameTimings[0].gpuFrameTime; still gives "0", it doesn't work on PC DX12 and OSX.

    A bit of good news, I have this error now: "d3d12: Profiler is enabled, but stable power state is not. GPU timing errors are expected."
    My question: are we to expect this system within the next 10 years?
     
    alexeyzakharov likes this.
  23. alexeyzakharov

    alexeyzakharov

    Joined:
    Jul 2, 2014
    Posts:
    507
    Hi!

    Yes. We are currently working on improving platform support of GPU profiling backend which is currently used for https://docs.unity3d.com/2020.2/Doc...Profiling.Recorder-gpuElapsedNanoseconds.html.
    And targeting ProfilerRecorder to be an umbrella api for cpu/gpu timings and other stats (including hardware stats in the future).
    That gives us ability to rewire FrameTimingManager implementation and get consistent support of GPU timings across all platforms/graphics api (*subject to driver support on some mobile platforms).
    Our current plan is to have stable GPU timings solution in 2021.2.
     
    Edy likes this.
  24. alexeyzakharov

    alexeyzakharov

    Joined:
    Jul 2, 2014
    Posts:
    507
    Would you be happy to share your thoughts on what do you expect from (gpu) timing system?
    The GPU frame timings is quite ambiguous term if we consider VSync and other things. And I would like to ensure the use case you are talking in mind will be covered.
     
  25. CGDever

    CGDever

    Joined:
    Dec 17, 2014
    Posts:
    156
    Thanks for the answer! Finger crossed!!! Сan't wait for alpha / beta!

    I would be more than happy to have at least all the things which this guy is talking about here:

    Also it would be great if this ^ test project could be shared among the community

    It would be cool if it would be possible to get the number of vertices, the number of polygons that have been rendered.
     
    alexeyzakharov likes this.
  26. alexeyzakharov

    alexeyzakharov

    Joined:
    Jul 2, 2014
    Posts:
    507
    Edy likes this.
  27. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    This is music to my ears! For us, both CPU and GPU timings are relevant. I understand that especially with multithreading, it gets quite complicated, so to keep things a little simpler, the question the API needs to answer would be: How much does work on the CPU contribute to our 11ms frame time budget, and how much does the GPU contribute to it, and how much time did we have left in the last frame?

    Oh ...

    Well, we're currently stuck with 2019.4. But at some point, the pain of staying with the version will outweigh the pain of having to rebuild significant parts of the project due to breaking changes that Unity introduced. And proper GPU and CPU runtime profiling weighs kind of heavy ;-)
     
    fct509 and alexeyzakharov like this.
  28. bfoddy

    bfoddy

    Joined:
    Mar 27, 2012
    Posts:
    85
    Here's what I read in your manual on the Dynamic Resolution page :

    and
    The sample code at the bottom of that page uses the FrameTimings API.

    So we spent a bunch of time implementing this feature using the supplied example code. Of course this leads to crashes in build. Chasing down the bug, of course we land at this forum thread, once again the only source of critical information about how Unity does or doesn't work. It sucks, guys. This happens to us at least once a month because you don't keep your docs up to date.

    It's understandable that you prefer this, but if your manual sends people off for multiple hours or days doing work that turns out to be a total waste of time, people are going to be annoyed no matter what you prefer.
     
    alexeyzakharov likes this.
  29. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,453
    Good evening,

    What platform did you build for and what Graphics API did you use?

    I never said you shouldn't get frustrated about this, but instead that that is perfectly understandable and likely a good force that can lead to action an change. My preference was to keep the tone civil. There's no conflict in keeping a civil tone while feeling frustrated.

    I'll dig in some more to get the manual page updated. Any details of where this doesn't work for you helps because some of that might be bugs that should be fixed instead. For that I need to know which Platfrom and which Graphics s API this doesn't work with for you.
     
  30. bfoddy

    bfoddy

    Joined:
    Mar 27, 2012
    Posts:
    85
    This was DirectX12 for Windows, Unity 2020.1.
     
    MartinTilo likes this.
  31. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,453
    Docs update still pending but DX12 windows support landed on 2020.2. The docs were possibly backported too far back.
     
    jashan likes this.
  32. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,453
    If FrameTimingManger doesn't work on Windows Standalone /UWP +DX12, please file a bug.
     
  33. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    Just a note, the docs still contain no hints at which platforms support FrameTimings.

    E.g. I can toggle "Enable Frame Timing Stats" in the player settings for Android (not XBox or anything, also not a shared setting as far as I can see), but not get any.

    https://docs.unity3d.com/2019.4/Doc...ce/PlayerSettings-enableFrameTimingStats.html
    Neither the 2019.4 (still in LTS) nor 2020.3 (also LTS) contain any info about supported platforms.
     
  34. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,362
    I don't understand the heuristic described in this video.
    It seems to me that, given a target of 16ms if gpuTime > 16ms then it's gpu bound and if cpuFrameTime>16ms then it's cpu bound and each is handled independently.
    so can someone explain why his heuristic is better?
     
  35. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    It's given just as an example. The only reason it's better is that it doesn't have hardcoded numbers.
    It just works under the assumption that if your latency is larger than half of GPU frame, you're GPU bound.
    Which is not always true, but will produce good enough results.
     
    laurentlavigne and MartinTilo like this.
  36. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    laurentlavigne, Edy and MartinTilo like this.
  37. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,362
    nice update! you know i'd be crazy enough to release a game on a beta version of unity if the switch player was ready for it

    overall experience in urp 10 and 8 is very negative: i was getting freeze jitter frames when using frame buffer resize so i removed GPU throttling entirely
    cpu throttling is still there and the heuristic is very Bébé Cadum: if cputime > gpu time + 5 then we're cpu bound, start throttling ai and physics

    funny thing is cpu throttling is very forgiving on enemies but it breaks the enjoyment of the game when the friendly units starts going all mushy so throttling is now only on enemies.

    it's home cooked
     
  38. Liam2349

    Liam2349

    Joined:
    Mar 10, 2016
    Posts:
    81
    Edy likes this.
  39. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,453
    That blogpost does refer to 2022.1, as does this post above:
    Also, I think it's pretty good that we hit Edy's prediction of 5 years while NOT abandoning it for a new experimental feature, but instead keeping at it until it works the right way within the initial feature. ;)
     
    Edy likes this.
  40. Liam2349

    Liam2349

    Joined:
    Mar 10, 2016
    Posts:
    81
    It's true, more commitment from Unity is a good thing.

    In the meantime, as I'm on 2021.3, do you know of any external tools that can show CPU and GPU frame times? My only find has been FpsVR, which works only when a SteamVR game is loaded.

    MSI Afterburner with the RivaTuner overlay doesn't seem able to separate frame times into CPU and GPU. I'm aware of an Nvidia program that may require a second PC, but I can't really use that.
     
  41. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Absolutely, I'm glad I failed that one :D
     
    MartinTilo likes this.
  42. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,453
    The last chapter in the Ultimate Guide to Profiling Unity Games covers native tools for platform & GPU specific profiling. Hopefully that should cover you until you can switch to 2022.
     
  43. Liam2349

    Liam2349

    Joined:
    Mar 10, 2016
    Posts:
    81
    Thanks I will definitely look through this. Perhaps it will help me to understand some CPU delays I've encountered.
     
    MartinTilo likes this.