Performance spikes due to WaitOnSwapChain (only on build)

Hi everyone,
I have been looking through what feels like hundreds of forums for an answer to my predicament but no ‘answer’ seems to work for me, so here I am, making my own specific question.

My issue arises from what the profiler identifies to be DXGI.WaitOnSwapChain, a process taking up around 99% of performance. It creates massive spikes periodically and I haven’t the faintest clue as to what might be causing it but no matter if I am not doing anything in the game, the map is disabled, the UI is disabled - even if its an empty scene - I get the same result. Its worth mentioning, I have heavily optimised my rendering in particular. When I play the game in the editor, it runs perfectly; just as beautifully smooth as I want it to be, but as soon as I build the project, while my fps counter gives me high numbers, the game has huge stutters and lurching (which I’m assuming is down to the performance spiking). I also have vsync disabled and no framerate specified but I have trialled through combinations of vsync being on and off and with different target frames; they have not been successful or ideal. If I have not specified enough information, then please let me know what I’m missing. I will attach a picture of the profiler below and any help would be greatly appreciated.


^ In editor - no issues here, everything runs just how I’d like


^ In Build - Huge spikes in GPU and CPU usage, the main culprit being WaitOnSwapChain.

Both readings above are with no Vsync and a framerate of as quick as possible (-1). This is how I’d like it to be by default but I would most likely add an option for vsync on and off in future.

Thanks in advance!!

This is explained in the documentation on Profiler Markers (the relevant part is WaitForLastPresent not WaitOnSwapChain):

<GraphicsAPIName>.WaitForLastPresent

Samples with this marker appear when the main thread waited for the GPU to flip the frame number to the screen (Time.frameCount - QualitySettings.maxQueuedFrames + 1). This means that if QualitySettings.maxQueuedFrames is greater than one, this time is spent waiting for the GPU to flip a frame that your application requested to render in a previous main thread frame.

For more details on this sample and an overview of Unity’s Frame Pipeline, see Unity’s blog post on fixing Delta Time.

i.e. your build is GPU-bound and the CPU is waiting for the GPU to finish rendering. You probably don’t see this in the editor because the editor itself is using a lot of CPU resources and the GPU ends up not being such a big bottleneck.

Ok, so have you any advice on how I might fix it? I’m fairly certain its not really an optimisation issue as like Ive mentioned: I have optimised a lot and it persists even in an empty scene. Thanks!!

I think WaitForLastPresent is a red herring. It’s not a spike in the usual sense that can cause frame drops, it just means the CPU has rendered enough frames ahead of the GPU and waits for it to catch up. It shouldn’t impact the rendering result.

You might want to try a GPU profiler to better see what’s happening there. The profiler screenshot you posted shows big “Other” spikes on the GPU. If the GPU cannot render frames fast enough, it would then cause the CPU to wait for it in WaitForLastPresent. You’d see that spike on the CPU side but the actual issue is on the GPU.

There’s also the Frame Timing Manager but I’m not sure how useful it’s data would be in this case.

Hi again Adrian,

I did check out the Frame Timing Manager but it wasn’t really making sense how to set it up. I have however, collected GPU usage through the Task Manager. Hopefully this is useful-
image
Above is what I got when running the build and it looks just fine to me but perhaps you can see something wrong.


And in editor…

Task Manager only shows you a very high-level view of the GPU, I meant an actual GPU profiler, usually offered by the graphics card vender. AMD, NVIDIA or Intel each have their own. They will show you exactly what is being executed on the graphics card and you should be able to see what the GPU is doing during those spikes.

I’ve been looking for a NVIDIA profiler but it’s not been straightforward (or maybe I’m just extremely stupid) and I can’t get any kind of profiler. If you could point me in a direction that would be wonderful. I’m sorry if this is supposed to be common knowledge!

I ran a test a few days ago as I haven’t found any further solutions. I made a new project with many similar features to my main project all apart from multiplayer and found that in both editor AND build the game runs as smooth as butter. So while I’m not entirely certain if the issue is definitely sourced from multiplayer, I would say it’s not unreasonable to suggest that it might be. Does anyone know if networking profiling comes under ‘Other’ in the CPU usage??

If anyone has any further guidance, it would be most appriciated

Hey, could you record this effect with Windows Performance Recorder? Instructions here: Recording a trace on PC

Use the CPU usage and GPU usage providers.

This can be caused by many things. Usually by something occurring on your machine the particular time and causing a stall in the graphics driver. Last time I looked at an issue like this, it turned out to be the keyboard RGB driver…

Hi,

Sorry for a slightly later reply, I’ve done what you’ve asked as best I can but I am quite new to this all so I’m not entirely sure what is relevant and what isn’t so I’ve taken many screenshots sorry!! Hopefully there is something valuable in these and I’ve done it correctly!

All following screenshots are of a analysis of a 30 second recording of the build running where the snapping issue with v-sync occurs. The application name is ‘pe.exe’ (great name I know)

The setup (please confirm if this is what you need!!):

The analysis:

Let me know if there is anything I’ve done wrong or what needs to be done further. Thank you for your time, this issue has plagued me for months now, I am grateful for anything.

Can you put the captured trace into a .zip file, upload it to some cloud storage (like Google drive) and send a link to it to me? You captured it correctly but those screenshots from the analyzer aren’t very helpful. I basically need to do wait analysis on it, as outlined here: CPU Usage (Precise) provider

Hopefully this works:

Let me know if it doesn’t!!
Thanks

Could you switch the logging mode to “File” from “Memory” and record me another trace? “Memory” uses a circular buffer which causes some events to get lost if the trace hitting memory usage thresholds. I am not seeing the recorded GPU activity and I suspect it’s caused by that.
“File” mode should not have that limitation.

I see you’re running without VSync. Does this also happen with VSync enabled?

Hopefully you will find both the v-sync enabled and disabled trace files in the zip attached. I have no idea if its useful or not but here are my NVIDIA settings as well:

And the Link:

Thanks so much

Something really bizarre is happening on your machine. Even though your monitor is 60 Hz, VSync limits that to 36-38 FPS. Without VSync, you’re running at ~700 fps. There doesn’t seem to be any user mode processes interfering with rendering but it isn’t completing at a constant pace. The GPU seems to not be too busy, and is spending some time in the Hardware Copy Queue. This isn’t a laptop it seems (given your CPU is i7-12700) which means that copying activity is unexpected. A few questions:

  1. Do you have a GSync monitor? If so, did you try disabling GSync to see if it changes anything?
  2. Did you try completely uninstalling and reinstalling Nvidia graphics drivers?
  3. What kind of cable do you use to connect your monitor to the computer? Which slot is it plugged into?
  4. How much free memory do you have available when while this is happening? Is there any chance you’re triggering memory compression/paging due to low memory pressure?
  5. Does this happen with any other games, that aren’t Unity based?

I cant answer all questions right now but I can tell you that I have tried g-sync changes and it has had no effect, I will try uninstalling and reinstalling my drivers (tomorrow), Im not entirely sure if this is correct but I think HDMI is the connecting cable, I believe I have plenty of memory because I have a terabyte of memory but I dunno if that changes when I run in (will investigate further tomorrow - with any instructions on how to monitor the memory??) and finally it is ONLY my unity games - other unity games that I haven’t made but that I’ve installed are working perfectly.

Edit: If you think it might be something to do with my computer I can send the build to friends and see how it fares on their machines.

Thanks

Can you double check which slot in the computer it’s plugged into, and whether it’s plugged into the GPU or the motherboard?

The trace shows you have 16 GB. I’m talking about RAM here, not disk.

Task manager should show you available and used memory.

That would help us eliminate or confirm this so yes it’d be helpful.

I have found that my connecting cable is not HDMI, its a display port connection and I am sure that it is plugged into the GPU. And yes I’m sorry, I do have 16GB of RAM. Unfortunately, just as I was checking these things and about to send the build and test the memory, something has gone wrong and now my monitor is on (I can see it is lit but still black) and so is my PC but no matter how well I insert and reinsert my connection cables (even using a HDMI), its not playing ball and I cant get anything rendering on my monitor so until I have this hardware issue resolved I will be inactive. Hopefully it is a small thing and it’ll be done quickly, I’ll send the build to friends and do all the other suggestions and get back to you with their results as soon as possible.

Thank you for your patience!

Ok so, I now have my PC cooperating again, however the DP cable doesn’t appear to be functioning so I have switched to HDMI connected to the GPU instead (the vsync problem persists). And here is information on the performance of the build from the Task Manager:

I have also recently ensured all my drivers are up to date and have installed all updates from the settings.

Thanks

Your memory commit is above the available memory, so it is possible some paging is in order (you see those spikes on the disk usage graph?). Would it be possible for you to run the game right after rebooting and seeing if those spikes remain? It’d be best if you added code to detect them, as opposed to looking at Unity profiler as I suspect Unity Editor is what is using up your memory.