XNA 的 CPU 使用率高

发布于 2024-12-21 22:33:38 字数 696 浏览 5 评论 0原文

我今天刚刚注意到,当我编译并运行一款新的 XNA 4.0 游戏时,其中一个 CPU 线程以 100% 的速度运行,并且帧速率下降到 54 FPS。

奇怪的是,有时它可以在 60 FPS 下运行,但随后就会下降到 54 FPS。

我以前没有注意到这种行为,所以我不知道这是否正常。我卸载了防病毒软件并重新安装了 XNA Game Studio、XNA Redistributable 和 .NET Framework 4。

如果我将 IsFixedTimeStep 设置为 false,则游戏以 60 FPS 运行,并且 CPU 使用率最低 (1-2%)。但据我所知,这需要我使用 ElapsedGameTime 进行速度计算,但我不知道该怎么做,因为我对 XNA 相当陌生。但有人说将其设置为 false 可以减少动画的抖动。

我已经检查了此论坛帖子,但没有人找到好的解决方案。

有人遇到过这个问题吗?

编辑: 我做了一些更多的研究,并实现了一个 FPS 计数器(直到现在,我用 Fraps 测量了它),我的计数器显示游戏以 60 FPS 运行(IsFixedTimeStep = true),所以这解决了 FPS 问题,但 CPU 较高用法仍然存在。有可能每个人都会遇到这种情况吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蘑菇王子 2024-12-28 22:33:38

根据 XBox Live Indie Games 论坛上的讨论,显然在某些处理器上(和操作系统)当使用默认值 Game.IsFixedTimeStep 时,XNA 会占用一个核心上的100% CPU 时间

一种常见的解决方案(也对我有用)是将以下内容放入您的Game构造函数中:

IsFixedTimeStep = false;

这是什么意思?

Game.IsFixedTimeStep 属性,当 true 时,确保您的帧 (Update(), Draw(), ...) 以 Game.TargetElapsedTime 中指定的固定时间间隔调用。默认为每秒 60 次调用

当 Game.IsFixedTimeStep = false 时,下一帧的调用将在前一帧完成时发生。下面的时间图表对此进行了说明:

在此处输入图像描述


此更改如何影响我的代码?

所有固定时间计算(移动计时等)都需要修改以适应可变时间步长。值得庆幸的是,这非常简单

假设您有

Vector3 velocity;
Vector3 position;

某个对象,并且您正在使用“默认”更新位置

position += velocity;

,这意味着对象的速度为每 60 *velocity.Length() 单位第二。每秒增加 60 次速度。

当您将该句子翻译成代码时,您会得到这个简单修改

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

简单地说:您将根据经过的时间来缩放添加的值

通过在执行移动(或计时等)的地方进行这些修改,您将确保您的游戏按照固定时间步长时的方式运行。

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.

ぃ双果 2024-12-28 22:33:38

对于游戏来说,高 CPU 使用率(一个核心 100%)不是问题。换句话说,这是预期的。当您编写游戏时使用 CPU 的方式要求您这样做。

打开代码环境,编写一个简单的程序,

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

打开CPU监视器,看到一个核心使用率100%。

现在你的游戏正在这样做:

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

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

所以基本上你调用 update()draw(),这占用了你必须计算一帧的 16ms 的大部分时间(你当您的游戏中有很多内容时,占据大部分时间)。

现在因为操作系统睡眠分辨率不准确 (如果您调用 sleep( 1ms ),它实际上可能会在您的应用再次唤醒之前休眠 20ms),会发生的情况是游戏永远不会调用O/S 系统函数SleepSleep 功能会导致您的游戏“睡过头”,并且游戏会显得迟缓且缓慢。

良好的 CPU 使用率并不值得拥有一个反应迟钝的游戏应用程序。所以标准是“忙等待”,在占用CPU的同时减少时间。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文