Hello
After updating my Unity project from 6.0.58 to 6.3 I am facing performance regression in the same scene and no code changes. After doing a CPU capture in PIX I found Gfx.WaitForGfxCommandsFromMainThread has jumped to 1.5ms from 0.2ms
Unity 6.3.1:
I am using GPU driven rendering in built in render pipeline and I am calling Graphics.RenderPrimitivesIndexedIndirect for all the static geos in Update(). Has anything changed in Unity 6.3 that I need to change my code or is this a regression?
Thanks
Gfx.WaitForGfxCommandsFromMainThread just means the render thread is idling, waiting for more commands. You should look at what the main thread is doing and compare that.
This is the main thread.
I am attaching my pix capture here
You’re completely CPU bound it seems. Furthermore, I found that over 40% of your frame time is spent in rendering callbacks. There one particularly egregious usage of Object.FindObjectsOfType, called from SetFirstPersonData.OnPreRender:
DeferredDecalRenderer.BuildCommandBuffer is using System.Linq, which isn’t quick either:
Addressing these should give you a substantial performance boost.
I’m not sure what exactly got slower in 6.3, but if you want to find out, compare the sampled functions for the main thread rather than the timeline view.
Thanks a lot for your response. These are indeed debug build shenanigans which either get converted into Stack in case of decals and the FindObjectOfType gets removed in the release build. I’ll share another capture one with 6.0 and other with 6.3 without these.
It looks like everything is taking a bit more time on 6.3
I am attaching both the pix captures in case I am missing something.
Thanks
The 6.3 version of your trace seems to have deep profiling enabled, whereas 6.0 does not. That definitely explains “everything” taking a bit longer as deep profiler has performance impact on everything. Can you disable it?
I am pretty sure I am not using deep profiling in 6.3. I have created another build just to confirm without the deep profiling support and attaching the capture here.
I am seeing the same difference in 6.0 & 6.3 in the newer build as well.
Thanks.
So this is what I saw:
The il2cpp::vm::Profiler calls generally indicate deep profiler is active.
Those things are not present in 6.0 capture:
I wonder if we have some kind of a bug that causes it to be activated for the build. How does the GameAssembly.dll size compare for 6.0 vs 6.3? Is 6.3 one measurably bigger?
Also, can you look at IL2CPP generated code? Can you see any lines containing ProfilerMethodSentry?
Ok, looks like my GameAssembly.dll was not getting replaced when I was making the build, I had to manually delete it and create a new build. Sorry about that.
I am attaching another capture and I dont see the il2cpp::vm::Profiler in this one.
The new GameAssembly.dll is a slightly larger by 2.5MB as compared to 6.0
This capture is again slower by the same amount as the previous one.
However I searched for ProfilerMethodSentry in the il2cpp output code but I couldn’t find any.
I made a build with Deep profiling and then I could find a lot of lines containing ProfilerMethodSentry.
Thanks
What’s the average frame time are you seeing for each version? From what I can tell, both of these run at around 500 frames per second (hard to tell exactly), but the framerate isn’t stable so it’s hard to do frame over frame comparison, as one frame takes 2 ms and the next one 2.5 ms. I think we’re beginning to exhaust the limits of helping you via discussions, we might need you to submit a bug report so that this could be properly investigated.
My frame times are around 2.3ms in Unity 6.3 and 1.6ms in Unity 6.0 when using non-development builds. I have a very tight frame budget and need to fit in a lot of other things.
I switched to using command buffer, fill the draw commands only once, and a separate command buffer for compute culling, all the required draw data is serialized and no new buffers are created every frame. Unfortunately the performance is still the same. This is mainly for static geometry. I am practically doing nothing after filling the command buffers for the first frame.
Also can you explain how can I avoid calling RenderPrimitiveIndexedIndirect every frame, as far as I remember Unity doesn’t cache this function.
We’re on BIRP + 6.0 and will be watching this thread carefully to see if there is in fact a broad perf regression in 6.3. Thanks for surfacing this @hrclogic.