【发布时间】:2011-07-06 14:13:03
【问题描述】:
在优化方面,我是一个相当大的新手。在我正在开发的当前游戏中,我设法优化了一个功能并减少了大约 0.5% 的 CPU 负载,这和我之前一样“棒极了”。
我的情况如下:我使用名为 ExEn 的 XNA 包装库在 MonoTouch 中开发了一款重物理游戏,并尽我所能尝试我发现很难让游戏在 iPhone4 上达到可玩的帧率(此时甚至不想考虑 iPhone3GS)。
性能下降几乎肯定是在物理计算中,如果我关闭物理,帧速率会急剧上升,如果我禁用一切,渲染,输入,音频,只是让物理性能在物理密集型情况下徘徊在 15fps 左右。
我使用 Instruments 来分析性能,这就是我得到的:http://i.imgur.com/FX25h.png 消耗最多性能的函数要么来自物理引擎(Farseer),要么来自它们调用的 ExEn XNA 包装函数(尤其是 Vector2.Max, Vector2.Min)。
我研究了这些函数,我知道 Farseer 在哪里可以通过引用而不是通过值将值传递给这些函数,所以这就是我能想到的唯一方法。这些函数本身基本上很简单相当于
这样的操作return new Vector2(Max(v1.x, v2.x), Max(v1.y, v2.y))
基本上,我觉得自己陷入了困境,而且我的能力和对代码优化的理解有限,我不确定我的选择是什么,或者我什至有什么选择(也许我应该蜷缩成胎儿的姿势哭泣? )。打开 LLVM 并内置发布后,我最多只能获得 15fps。我确实设法通过降低物理精度将游戏提高到 30fps,但这使得许多关卡根本无法玩,因为身体彼此相交并坍塌。
所以我的问题是,这是一个失败的原因还是我可以做些什么来提高性能?
【问题讨论】:
-
我认为您不应该关注库函数,而应该关注调用它们的函数。这些函数很简单,这意味着您经常调用它们。查看代码并问自己:为什么我这么频繁地打电话给他们?当然,分析器应该告诉您应该关注代码的哪些部分。
-
函数调用来自物理引擎,调用如此频繁的原因是物理引擎在每个更新周期都需要获取场景中所有物体的AABB盒子并检查交叉点。物理引擎本身由比我聪明得多的人进行了高度优化,所以我不确定在这方面我能做些什么。
-
请记住,每次创建“新 Vector2”时,GC 都必须在某个时候回收它。进行就地替换可能会更好:“target.x = Max(v1.x, v2.x); target.y = Max(v1.y, v2.y);”。
-
Vector2 是一个结构体,应该由堆栈而不是 GC 处理。如果是这样,那么我会说无论你做什么,单声道都不会给你在单声道上的 Farseer 物理提供良好的性能。如果单声道工作正常,只要您不动态添加/删除主体/几何体,Farseer 就应该以零分配/解除分配运行。
-
专注于路口检测。特别是如果你周围有很多物体,你可能需要找到一个局部交叉点例程(在一步中彼此相距很远的物体......实际上不会在下一步重叠,是吗?)。
标签: c# iphone mono xna xamarin.ios