8

I just noticed today, that when I compile and run a new XNA 4.0 game, one of CPU threads is running at 100% and the framerate drops to 54 FPS.

The weird thing is that sometimes it works at 60 FPS, but then it just drops to 54 FPS.

I haven't noticed this behaviour before, so I don't know if this is normal. I uninstalled my antivirus and reinstalled XNA Game Studio, XNA Redistributable and .NET Framework 4.

If I set IsFixedTimeStep to false, the game runs at 60 FPS and CPU usage is minimal (1-2%). but as far as I know, this requires me to do velocity calculations using ElapsedGameTime, but I don't know how to do it, since I'm fairly new to XNA. But some say that setting it to false reduces jerky animations.

I already checked this forum thread, but no one has found a good solution.

Has anyone experienced this problem?

EDIT: I did some more research and I implemented a FPS counter (until now, I measured it with Fraps), and my counter shows the game running at 60 FPS (with IsFixedTimeStep = true), so this solves the FPS issue, but the high CPU usage remains. Is it possible that this happens to everyone?

Klemen Košir
  • 266
  • 3
  • 10
  • Had this problem too, was giving me a real headache trying to nail it down, since profiling would only tell me the time was being spent somewhere in framework code. Interestingly, if the program is not in the foreground, it continues updating/drawing/running correctly, but CPU usage drops to normal. – Cheezmeister Jun 15 '12 at 05:20
  • How many cores do you have? In general the ["busy wait"](http://en.wikipedia.org/wiki/Busy_waiting) of the game loop `while(1) { update(); draw(); }` never sleeps (otherwise the game will lag), so you should expect at least 100% of _one logical core_ to be utilized. (so if you had a dual core cpu it should be 50%, dual core with hyperthreading, should be around 25%) – bobobobo Sep 11 '12 at 01:37

2 Answers2

19

According to this discussion on XBox Live Indie Games forum , apparently on some processors (and OS-s) XNA takes up 100% CPU time on one core when the default value of Game.IsFixedTimeStep is used.

A common solution (one that worked for me as well) is to put the following in your Game constructor:

IsFixedTimeStep = false;

What does it mean?

The Game.IsFixedTimeStep property, when true, ensures that your frame (Update(), Draw(), ...) is called at a fixed time interval specified in Game.TargetElapsedTime. This defaults to 60 calls per second.

When Game.IsFixedTimeStep = false, the calls to the next frame will happen when the previous one is finished. This is illustrated in the time graph below:

enter image description here


How does this change affect my code?

All fixed time calculations (movements, timings, etc.) will need to be modified to accommodate variable time steps. Thankfully, this is very simple.

Suppose you had

Vector3 velocity;
Vector3 position;

for some object, and you are updating the position with

position += velocity;

On default, this would mean that the speed of your object is 60 * velocity.Length() units per second. You add velocity 60 times each second.

When you translate that sentence into code, you get this simple modification:

position += velocity * 60 * gameTime.ElapsedGameTime.TotalSeconds;

To put it simple: you're scaling the values you add based on how much time has passed.

By making these modifications in places where you perform moving (or timing, etc.), you'll ensure that your game acts as it would back when it was fixed time step.

neeKo
  • 4,280
  • 23
  • 31
  • This really makes everything harder. Up until now I only needed to add the velocity to the current position. Is there really no other way to solve this issue? – Klemen Košir Dec 18 '11 at 19:27
  • 1
    Integrating my updates with GameTime was one of the best things to ever happen to my XNA application, it's definitely worth the (really pretty minor) graft. – Owen Dec 18 '11 at 20:06
  • Dear Lord, it uses a busy loop for fixed step? *And* it defaults to using it?? Microsoft, I thought you knew better! – Cheezmeister Jun 15 '12 at 05:16
  • Regarding your "edit 2", I don't see how a fixed time step would affect velocity -- it's still the same amount of time being elapsed, just not in the same increments! – Cameron Aug 07 '12 at 19:10
  • You're trying to fix a non-problem. 100% CPU usage on one core is expected for a game app – bobobobo Sep 11 '12 at 01:50
-1

High CPU usage (100% on one core) is a non-problem for games. In other words, it's expected. The way you're using the CPU when you write a game demands you do this.

Open the code environment and write a simple program

void main(){
    while(1) puts( "aaah" ) ;
}

Open the CPU monitor and see that 100% of one core is used.

Now your game is doing this:

void main(){
    while(1){
        update() ;
        draw() ;

        while( getTimeElapsedThisFrame() < 1.0/60.0 ) ; // busy wait, until 16ms have passed
    }
}

So basically you call update() and draw(), and that takes up most of the 16ms you have to compute a frame (which you will take up most of when your game has a lot of stuff in it).

Now because O/S sleep resolution is not exact (if you call sleep( 1ms ), it may actually sleep for 20ms before your app wakes up again), what happens is games don't ever call the O/S system function Sleep. The Sleep function would cause your game to "oversleep" as it were and the game would appear laggy and slow.

Good CPU usage isn't worth having an unresponsive game app. So the standard is to "busy wait" and whittle away the time while hogging the CPU.

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • I disagree. A game can be [GPU or CPU bound](http://blogs.msdn.com/b/shawnhar/archive/2008/03/31/an-elf-in-a-box.aspx). If it's GPU bound, which it is likely to be for graphics heavy games, then the CPU spends the portion of that time idle. But even if you would increase your CPU time in those with additional logic, that wouldn't be the your input logic, as `Update()` is called once per frame. The responsiveness would remain the same. And besides, setting `IsFixedTimeStep = false` tells XNA to call frames (update, draw) **as fast as it can**, as opposed to in a fixed interval. – neeKo Nov 08 '12 at 14:20
  • CPU bound or GPU bound only refers to the bottleneck being either the CPU or GPU. That doesn't matter here. The code I showed above ___shows what happens inside the XNA framework___ when a frame is being drawn, and shows why you should expect _at least_ 100% of __one core__ to be in use at all times while your game is running. – bobobobo Nov 08 '12 at 16:25
  • 1
    I still disagree. Create an XNA Game project and run it. Does it take 100% on any core? For me it doesn't. On a different PC it did, **until I made the change**. Even this infinite loop you posted never uses 100% - [check it out](http://i.imgur.com/qgn1e.png). – neeKo Nov 08 '12 at 16:45
  • It is using 100% of one core (`1 core/8`=12.5% of your total available CPU). What you're seeing there (the 100% load being _redistributed_ among your 8 cores) must have a name, but I don't know what it is. – bobobobo Nov 15 '12 at 18:56
  • 1
    Your reasoning is: game applications have a loop, therefore they have to use 100% CPU on a core. But if you actually run an XNA Game project, you will not get 100% usage on a core - so your reasoning is wrong. In case you don't want to check it out for yourself, [here's an example](http://i.imgur.com/cEk6Z.png). Therefore the 100% usage capped on one core was actually a real problem that only happens rarely and on some configurations. – neeKo Nov 15 '12 at 19:29