这个问题我可能应该早点提出,但我并不急于在MonoTouch中使用p / invoke类型的东西。
基本上我遇到了与大量浮点运算有关的性能问题,特别是涉及最小/最大函数,向量乘法和类似物(基本上检测不同类型的形状是否相交)。
这些操作的原因是因为用C#编写的2D物理引擎。
在某些平台上,例如Windows Phone 7和Xbox 360,物理引擎运行时没有任何障碍,它会窃取一些CPU周期,但留下足够的数据来确保游戏以稳定的帧速率运行。
问题在于在iPhone上运行MonoTouch。看起来MonoToch并不是那么多浮点运算和iPhone(甚至iPad 2)发现自己受到严重影响而物理成为明显的性能瓶颈。我profiled the performance它归结为一组相对基本的数学函数I mentioned before并且没有真正优化这些函数的方法,物理引擎本身写得很好而且我看不到任何显而易见的地方都在滞后,坦率地说我怀疑它作为2D C#物理引擎有什么问题。
为此,我决定找到一个用C语言编写的物理引擎(如果可能的话,还是C ++)并将其与主MonoTouch应用程序连接起来。我的理由是,由于MonoTouch中的性能问题可能与MonoTouch编译器无法编译.net代码以及Wp7 / xbox 360 JIT编译器的运行速度(这是可以理解的)有关,这一点可能与单点触控有关。并以原生方式运行它们有助于提高性能。
所以我的想法是我将使用Box2D,编写一堆静态包装函数(如CreateWorld(),CreateBox(),GetBodyPosition(int id)等等)并将所有内容挂钩到via p /调用功能并将其全部集成到我的物理包装器类中,这样核心游戏逻辑只需要很少甚至不需要修改,我可以保持原始代码设计的完整性,但也可以通过物理运行中的事实来提高性能。本地人C.
但这让我思考,性能问题源于非常简单直接的数学函数,简单的乘法和大小比较。如果通过p / invoke运行函数可以提高速度,那么只需将Vector2.Max等函数重写为C函数并调用它也可以提高性能吗?
然而,这似乎有点牵强,如果不是Mono那样做的话呢?
所以我想我的整体问题是,静态链接的本机库在从p / invoke调用时是否比MonoTouch编译的等效C#函数表现更好?
答案 0 :(得分:3)
实际上只有一种方法可以确定它是否更快:对您的案例进行基准测试。可能是您用于本机库的c编译器能够比mono的jit更优化,或者它可能只是不适合您的特定工作负载的cpu。
如果您想尝试使用本机库,请记住,您不希望经常从托管中调用本机代码,每个托管到本机转换的性能都会受到显着影响(重要性取决于很多因素,但更少的过渡总是更好。)
那就是说,我的个人猜测是单声道jit不能处理浮点运算(它之前已经出现过问题,我现在还不记得这些问题是否仍然存在)也没有在哪个cpus上,所以你将从使用本地库中受益。
答案 1 :(得分:2)
如果你有代码的关键部分,你可以尝试使用“unsafe”来避免数组访问的自动范围检查。对于短数组,如2或3向量和简单操作(如规范或点积),它可能会产生影响。
简单的数学运算不应该慢,但如果没有分析结果,很难分辨代码的哪些部分会变慢。如果本机版本大量使用sse,或者您的托管版本无意中使用了大量拳击等可能导致差异。
要使P / invoke有用,你应该做一些做很多工作的调用,所以如果你可以在一次调用本地dll时更新整个状态可能会很有用。但我绝对不会尝试将琐碎的函数原生化。
答案 2 :(得分:1)
除了Rolf的出色回应之外,您还可以考虑在构建游戏时使用LLVM优化。
我觉得令人惊讶的是Windows Phone 7比Mono的静态编译器具有更好的JIT