使用P/invoke来提高性能,可行还是空想?

3
这是一个我可能应该早点问的问题,但在急于使用MonoTouch中的p/invoke类型功能时没有问出来。基本上,我遇到了与大量浮点运算有关的性能问题,特别是涉及min/max函数、向量乘法和类似的东西(基本上是检测不同形状是否相交)。这些操作的原因是因为使用了C#编写的2D物理引擎。在某些平台上,如Windows Phone 7和Xbox 360,物理引擎可以无缝运行,它会占用一些CPU周期,但留下足够的资源来确保游戏以稳定的帧速率运行。
问题出现在运行在iPhone上的MonoTouch。看起来MonoToch在处理如此多的浮点运算时并不那么出色,而iPhone(甚至是iPad 2)发现自己受到严重影响,物理学成为明显的性能瓶颈。我已经分析了性能,结果表明一组相对基本的数学函数就像我之前提到的一样,没有真正优化这些函数的方法,物理引擎本身编写得非常好,我看不出它有任何明显的滞后,并且坦率地说,我怀疑这是否是一个2D C#物理引擎有问题。
为此,我决定找到一个用C(或如果可能的话用C++)编写的物理引擎,并将其与主要的MonoTouch应用程序连接起来。我的理由是,由于MonoTouch编译器不能像Wp7/xbox 360 JIT编译器那样将.net代码编译为运行速度很快的代码(这是可以理解的),将东西移出MonoTouch并以本地方式运行将有助于提高性能。
所以我的想法是使用Box2D,编写一堆静态包装函数(例如CreateWorld(),CreateBox(),GetBodyPosition(int id)等),并通过p/invoke功能将所有内容挂钩到我的物理包装类中,这样核心游戏逻辑将需要最少或不需要修改,并且我可以保持原始代码设计的完整性,但由于物理运行在本机C中,还可以获得性能提升。

但这让我想到,性能问题源于非常简单和直接的数学函数,如简单的乘法和大小比较。如果通过p/invoke运行函数会提高速度,那么像Vector2.Max这样的函数重新编写为C函数并调用是否也会提高性能呢?

然而,这似乎有些牵强,如果是这样,Mono难道不会自动执行吗?

所以我总的问题是,当从p/invoke调用时,静态链接的本机库是否比由MonoTouch编译的等效C#函数执行得更好?

3个回答

3
只有一种方法可以确定它是否更快:基准测试您的情况。可能您用于本地库的c编译器能够优化超过mono的jit,或者仅仅是cpu不适合特定工作负载。
如果您想尝试使用本地库,请记住您不想经常从托管调用本机代码,对于每个托管到本机转换都会产生显着的性能损失(这种影响的严重程度取决于很多因素,但较少的转换总是更好)。
话虽如此,我个人猜测是mono jit处理浮点运算的能力不如其应该(之前在某些cpu上存在此问题,现在是否还存在以及在哪些cpu上存在我不记得了),因此您将受益于使用本地库。

你是指与拇指编译相关的问题吗?我不确定这是否只适用于Mono,但我已经确保关闭了它,因为据说它会对浮点运算产生性能影响。我的目标是尽可能少地使用托管代码,并将尽可能多的操作推迟到本地,基本上整个物理引擎都将在本地运行,并且仅在最小次数交互以保持托管端的值更新(即场景状态、所有物体的位置等等)。 - meds
问题可能出在拇指编译上,我不确定,只记得在某处读到过浮点数计算问题。不过你的方法看起来是从本地代码中获得所有可能的好处的正确方法。 - Rolf Bjarne Kvinge

2
如果你的代码中有一些关键部分,你可以尝试使用"unsafe"来避免数组访问的自动范围检查。对于像2或3向量这样的短数组和简单操作(如norm或点积),它可能会产生影响。
简单的数学运算不应该更慢,但是很难确定哪些代码部分更慢,需要通过分析结果来确定。如果本地版本大量使用sse或者你的托管版本无意中使用了大量的装箱等,那么可能会导致差异。
为了使P/invoke有用,您应该进行少量调用并处理大量工作,因此如果您可以在一次调用本地dll时更新整个状态,那么它可能很有用。但我绝对不会尝试将微不足道的函数变成本地函数。

1
除了Rolf的出色回答,您可能考虑在构建游戏时使用LLVM优化。
我发现令人惊讶的是,Windows Phone 7拥有比Mono的静态编译器更好的JIT。

我确实使用LLVM编译,但遗憾的是改进并不明显。你认为WP7硬件可能比iPhone4硬件更强大,因此在相同的代码上WP7可以更好地管理帧率吗?它们都有1ghz处理器,但来自不同的供应商。尽管如此,iPad 2的规格必须比WP7更好,但仍然在游戏中出现延迟,并且提供的帧率比WP7设备更低... - meds
我很想看看你的代码为什么运行缓慢,我们可以使用分析器来查看它。 - miguel.de.icaza
我很乐意让你查看代码,请给我发电子邮件至jabberworx@gmail.com,我会把项目发送给你。 - meds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接