views:

305

answers:

4

Hi folks!

I have a WinForms application that uses XNA to animate 3D models in a control. The app have been doing just fine for months but recently I've started to experience periodic pauses in the animation. Setting out to investigate what is going on I have established these facts:

  1. It happens on my machine only, other machines works fine
  2. Removing everything from my render loop does not improve the problem

In 2. I didn't actually remove everything, I limited my loop to set the viewport on my GraphicsDevice and then do a GraphicsDevice.Present.

Trying to dig further I fired up PIX to capture some statistics. Screenshots of two PIX runs can be viewed here (Run6) and here (Run14). Run6 is using my original render loop and Run14 is using the bare-bones Present loop.

PIX tells me that the GPU is periodically doing something, and I assume this is causing the pauses. What could be the cause of this? Or how do I go about finding out what the GPU is actually doing?

Update: since I usually trust my code to be perfect (who's laughing?) I started a new XNA project from scratch to see if it exhibit the same behavior. So starting a new XNA 3.1 Windows Game project and running PIX I get this timeline. The same periodic pauses. So the problem must be lower in the stack, in XNA or Direct3D.

So PIX shows that the GPU is working on something, I can see the list of DX calls made within each frame and the timing calculations shows that the pause occurs during (or after) the IDirect3DDevice9::Present call.

Update 2: I had previously installed and uninstalled XNA 4.0 CTP on the problematic machine. I cannot be certain that this is related but I thought that perhaps a reinstall of the XNA Game Studio 3.1 bits could make a difference. Turns out it did.

The underlying question remains the same (and the bounty is still up): what could affect XNA 3.1 (or DirectX) to make it behave like this and is there any logging/tracing power tool for the DirectX and/or GPU level out there that could shed some light on what is going on?

Note: I'm using XNA 3.1 on a Windows 7 x64 dual-core machine with 8GB RAM.

Note2: also posted this question on the XNA Creators forums here.

+1  A: 

Hmm ... this seems to be occurring on the GPU, however it sounds like a CPU garbage collection issue. Can you run the CLR profiler and see if you can see any spikes in GC activity that you can correlate to the slowdowns?

I agree that it sounds unlikely since you can clearly see it in PIX, but it might offer a clue as to the cause.

Joel Martinez
Agree that GC is a posibility and I did some tests but they showed no suspicious behavior. Also, bare loop is virtually instanciating nothing, only a Rectangle for the Present call...
Peter Lillevold
A: 

If it's only happening on your own machine, then could it be drivers? Forgive me for being skeptical, but it's a 64 bit machine after all :D

YellPika
The XNA FX and Direct3D work fine on Windows 7 x64 - at least with an ATI GPU (and I would assume the same for NVIDIA).
Bjoern
As mentioned, rendering have been working fine on the same drivers, that is why I tend to blame XNA 4.0 CTP right now. But yes, there was a newer gfx driver which I installed but that did not remedy the problem.
Peter Lillevold
+1  A: 

You could try to see if you can find something with Xperf that is close to your periodically problem, do not run your application but keep the programs open that would normally run besides your application. You could also try to do it again with the application running but it could give a cluttered view.

  1. Start the tracing, do this in an elevated prompt.

    xperf -on BASE+LATENCY -stackWalk Profile

  2. Wait for a fair amount of time to be sure that the problem is traced.

  3. Stop the tracing and open it like this.

    xperf -d trace.etl
    xperfview trace.etl

  4. Analyze by looking at the graphs and consulting tables of specific intervals and see if you can find something that is related to the problem, the highest chance on finding it would be in the DPC and Interrupts section. But it might as well be something odd at the CPU or I/O section. Good luck!

Also more information on Xperf and how to obtain it, hopefully this delivers results.


If not, you can alternatively try GPUView which has been used for improvements in DWM,
this is also included next to Xperf with the Windows Performance Toolkit so you can easily try both!

log v

... wait for a fair amount of time to be sure that the problem is traced ...

log

gpuview merged.etl

In the case that gpuview gets out of memory you can try to add "/limit 3" or remove the v.

Read the documentation of the tools if you are stuck somewhere.

TomWij
+1 Yay for the xperf tools! This is definitively useful!
Peter Lillevold
A: 

This looks like either a vsync issue or GPU in its last throes. Since going back to a different version fixed it, and the "bottleneck" is in IDirect3DDevice9::Present lets go with the former option.

I'm not familiar with XNA so I don't know how much of the workings of D3D are exposed, but do you know what your PresentationParameters are set to?

Specifically try setting the swap effect set to Discard.

Andrew Khosravian
Well, the XNA layer in the last test is pretty thin, each frame rendering includes only five DX calls ending with `IDirect3DDevice9::Present(NULL,NULL,NULL,NULL)`.
Peter Lillevold
Did a quick check on the internet to get the XNA terminology, and it looks like the PresentationParameters are passed in as the last argument to the GraphicsDevice constructor. It doesn't look like you can change the swap effect in 4.0 even though it is available in 3.1. Try setting the PresentInterval on your PresentParameters to Immediate. See http://msdn.microsoft.com/en-us/library/ff433790(v=XNAGameStudio.40).aspx and http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.presentinterval(v=XNAGameStudio.40).aspx
Andrew Khosravian
Just as a FYI: The swap effect is a member of the PresentationParameters class named PresentationInterval now (see http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.presentationparameters_members(v=XNAGameStudio.40).aspx and http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.presentinterval(v=XNAGameStudio.40).aspx).
Bjoern