简体   繁体   English

XNA的CPU使用率很高

[英]High CPU usage with XNA

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. 我今天刚刚注意到,当我编译并运行一个新的XNA 4.0游戏时,其中一个CPU线程以100%运行,帧速率降至54 FPS。

The weird thing is that sometimes it works at 60 FPS, but then it just drops to 54 FPS. 奇怪的是,它有时会以60 FPS的速度运行,但之后只会下降到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. 我卸载了我的防病毒软件并重新安装了XNA Game Studio,XNA Redistributable和.NET Framework 4。

If I set IsFixedTimeStep to false, the game runs at 60 FPS and CPU usage is minimal (1-2%). 如果我将IsFixedTimeStep设置为false,则游戏以60 FPS运行,CPU使用率最低(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. 但据我所知,这需要我使用ElapsedGameTime进行速度计算,但我不知道该怎么做,因为我对XNA很新。 But some say that setting it to false reduces jerky animations. 但是有人说将其设置为false可以减少抖动动画。

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. 编辑:我做了一些研究,我实施了一个FPS计数器(直到现在,我用Fraps测量它),我的计数器显示游戏以60 FPS运行(IsFixedTimeStep = true),所以这解决了FPS问题,但是CPU使用率仍然很高。 Is it possible that this happens to everyone? 这可能发生在每个人身上吗?

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 . 根据对XBox Live Indie Games论坛的讨论 ,显然在一些处理器(和OS-s) 上,当 使用 Game.IsFixedTimeStep 的默认值时, XNA 在一个核心上占用100%的CPU时间

A common solution (one that worked for me as well) is to put the following in your Game constructor: 一个常见的解决方案 (也适用于我)是将以下内容放在Game构造函数中:

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 . Game.IsFixedTimeStep属性,如果为true ,则确保以Game.TargetElapsedTime指定的固定时间间隔调用您的帧( Update()Draw() ,...)。 This defaults to 60 calls per second . 默认为每秒60个呼叫

When Game.IsFixedTimeStep = false , the calls to the next frame will happen when the previous one is finished. Game.IsFixedTimeStep = false时,对前一帧的调用将在前一帧完成时发生。 This is illustrated in the time graph below: 这在下面的时间图中说明:

在此输入图像描述


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. 默认情况下,这意味着对象的速度为 60 * velocity.Length()单位/秒。 You add velocity 60 times each second. 你每秒增加速度60次。

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. 通过在您执行移动(或定时等)的位置进行这些修改,您将确保您的游戏在固定时间步长时的行为。

High CPU usage (100% on one core) is a non-problem for games. 高CPU使用率(一个核心100%)对游戏来说不是问题 In other words, it's expected. 换句话说,它是预期的。 The way you're using the CPU when you write a game demands you do this. 你在编写游戏时使用CPU的方式要求你这样做。

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. 打开CPU监视器,看到使用了100%的一个核心。

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). 所以基本上你调用update()draw() ,这占用了你需要计算一个帧的大部分16ms(当你的游戏中有很多东西时你占用大部分时间)。

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 . 现在因为O / S睡眠分辨率不准确 (如果你叫sleep( 1ms ) ,它实际上可能会在你的应用程序再次唤醒之前睡眠20ms ),会发生的事情是游戏永远不会调用O / S系统功能Sleep The Sleep function would cause your game to "oversleep" as it were and the game would appear laggy and slow. Sleep功能会让您的游戏“过度睡眠”,游戏会出现滞后和缓慢。

Good CPU usage isn't worth having an unresponsive game app. 良好的CPU使用率不值得拥有一个反应迟钝的游戏应用程序。 So the standard is to "busy wait" and whittle away the time while hogging the CPU. 所以标准是“忙等待”并且在占用CPU时缩短时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM