Sorry I’m late to the party. Hopefully you’re still watching this thread.
Who are you?
Greg Nagel, Free Range Games
What kind of game are you trying to build or would like to build?
We’re all over the map. Mostly desktop, mobile, some console, web. Big project right now is Labyrinth.
How does the Profiler fit into that? What use-cases do you have?
Mostly hunting down GC. Allocations cause more trouble than anything. Otherwise, performance problems, usually graphics-related, sometime scripting: what do we shave from memory on mobile, or how do we get the framerate down. I look at CPU, GPU and memory. I also end up trying to profile custom inspector work sometimes. Editor profiling tends to be harder to decipher than runtime.
What are the GOOD things about the Profiler that you like?
- It shows GC pretty clearly. I don’t know how we’d have figured out half of our problems without that.
- Pretty good at connecting to whatever device I’m looking at. (Though a few times it’s been overeager and profiled my coworker’s machine—I think you fixed that bug.)
- It accounts for pretty much everything that goes on in a frame. While I want better filtering, you can’t trust a profiler that doesn’t give you access to the whole picture.
What are the BAD things about the Profiler that you dislike?
-
+1 to everything benblo said. I have had issues will all of it, down to the triangle-shaped frames.
-
Especially profiling loading. That cannot be overstated. You’ve done so much to help improve load times lately, but it’s easy for us to do stupid things and not have any way to determine what they are.
-
The black-box overhead is especially prevalent on consoles. Please tell us what it is, at least in broad strokes.
-
That last frame likes to hide behind the edge of the window, and it’s really hard catch the right frame when you’ve got editor profiling on. When you’re trying to profile the first few frames after a compile, it takes more than a few tries, and the UnityEngine.Profiler API doesn’t work too well with editor profiling. (I am OK with editor profiling being a second-class feature though.)
How can we make it BETTER?
A) If we run out of samples for a frame, we really need to see those samples! Can you at least keep the samples you’ve already collected, and lump everything else into some “untracked” sample?
B) All it takes is one return in the wrong place to make BeginFrame and EndFrame not match up in an incredibly hard way to detect. Or you might get an exception. It’s easy enough to make foolproof with an IDisposable hack. eg: using (Profiler.Sample(“Foo”, obj)) { /* … */ } (Only downside is you can’t use ConditionalAttribute to compile out a method with a return value.)
C) Profiler.BeginSample is one of the methods that I keep wishing could be called from any thread. It could be a no-op, even, though especially the allocation information would be useful.
Side issue: There’s no thread-safe way to check if you’re even allowed to call the Unity API.
D) Building on benblo’s filtering: Filtering out a root node (or any hierarchy) is useful, though more often I want to filter out every node with the same name, but keep those nodes’ children. (Saves a recompile, and would also make a deep profile more useful.)
E) When you have a sample for a constructor (under Loading.ReadObject, for instance) can you also capture the cost of the object allocation? Maybe in a separate sample. The question I’m usually asking here is “how much time did I spend deserializing this type of field in a SerializedObject”?
If you were to put samples on all C# allocations by the Unity API, you would give us a lot more information to work with.
F) Maybe this is beyond your scope, but fixing some allocations in OnGUI would certainly go a long way to improving the profiler window’s performance. One of the biggest problems I see is that pretty much every string returned by the Unity API allocates, including UnityEngine.Object.name. Caching a lot more of them (even just checking a cached string field against the C++ string for changes each time) would mitigate a number of issues.
G) And this might be off-topic, but it’d be nice if we didn’t have to use the OnGUI Rendering Statistics Gizmo for checking draw calls, etc. As with a lot of .NET stuff, this is a solved problem, and the way servers handle this is ETW, which is the chosen technology for this sort of profiling in Core CLR. Notably, System.Diagnostics.Tracing.EventSource/EventLogTraceListener provide an fast, allocation-free way to listen to events, and you hardly pay for it if you don’t listen to those events. (The Core CLR version also hooks into Windows Event Reporting or Instruments, etc, but I don’t know if we need that. Maybe it’d help integrate with IL2CPP profiling.)
If you gave us per-frame info in ETW, it would let us collect statistics in whatever way we want, with our own logic. So we could collect statistics over X frames, only look at events we care about, use open source libraries to process the data, etc.
If you gave us ETW events whenever Unity invoked C#, we could know how many update calls were happening from frame to frame or track down an unexpected usage of an [InitializeOnLoadMethod] in an otherwise opaque library. Or collect stack traces in debug for coroutines (see this).