降低本地<->;单触式管理交互

本文关键字:单触式 管理 交互 gt lt- | 更新日期: 2023-09-27 18:00:21

我正在使用一个本机库,我为该库编写了monotouch(我们现在应该将其命名为Xamarin.iOS吗?)绑定。

重写C#中一些常用的方法会显示出严重的性能降级,即使函数的核心什么都不做或返回base。X()。仪器确认问题以及在管理<->中花费的时间本地交互。

有没有办法从一方或另一方(本地或托管)加快速度?或者,当P/在MT中调用时,这是要支付的税吗?

我打的玻璃天花板大约是50000个电话/秒。

[更新2013/02/22]举一些上下文或例子,以下是我正在做的事情。我在玩椰子2d运动学(没有花栗鼠)。为了管理我自己的精灵位置,我必须覆盖

CGAffineTransform NodeToParentTransform { get; }

bool Dirty { get; }

前者返回一个矩阵,并戳原生面以获得ScaleX、ScaleY、RotationX等参数。RotationY和AnchorPointInPoints,后者无条件返回true

目前,我降低成本的尝试在一定程度上是成功的,因为通过将本机代码更改为具有一个不指向任何属性的单点覆盖,我可以获得25%到50%的加速。

-(BOOL) dirty:(CGAffineTransform*)nodeToParentTransform rotationX:(float)rotX rotationY:(float)rotY scaleX:(float)scaleX scaleY:(float)scaleY anchorPointInPoints:(CGPoint)anchorPointInPoints;

我现在的3500精灵的速度达到了几乎可以接受的25-30ps,但我仍然想走得更远。而且也不必修补本地源。

[更新2013/02/22]这是一个你可以用来测试的样本https://github.com/StephaneDelcroix/mt-speed.它包含一个过于简化的一阶运动学引擎,3501个实体和精灵。

这里有趣的课是KinematicSprite。该代码适用于修改后的cocos2d版本(包含在cocos2d.dll中)。您可以通过注释掉新的Dirty函数并取消注释NodeToParentTransform和旧的Dirty,使其适用于库存cocos2d和cocos2d绑定。根据mono-touch中的子类绑定类型,它只适用于设备。我在iPad mini上可以获得20到22.5帧/秒的速度。

降低本地<->;单触式管理交互

我们现在应该把它命名为Xamarin.iOS吗?

是的,现在是Xamarin.iOS:-)

或者,当p/在MT中调用时,这是要支付的税吗?

在从托管代码和非托管代码转换时,需要做很多事情。蹦床处理这些:封送参数和返回值,处理托管异常,处理本机异常。。。

此外,您可能会多次执行转换,例如new Managed ();调用本机init*,后者调用(本机)setFoo:,后者返回(托管)Foo setter(并返回…调用方)。

因此,即使每个部分都很快,但如果你不进行操作(或只调用base),仍然会引起注意,因为没有太多用户时间可以摊销。

有没有办法从一方或另一方(本地或托管)加快速度?

是的。首先,确保您测量真实的东西。例如

  • 上述任务与模拟器和设备不同,例如JIT与AOT,x86和ARM的ABI不同;

  • 调试和发布构建配置也将使用不同的代码;

因此,您可能想要在iOS(ARM)设备上测量Release版本。

您应该做的下一件事是确保启用Link all assembly(如果您有非SDK绑定,例如Cocos2d)。这不会改变蹦床,但当你调用base时,你调用的是绑定代码。

事实证明,链接器在绑定方面非常聪明,可以删除您的情况下不需要的代码。例如

  • 删除与IsDirectBinding相关的检查和分支
  • 删除与NewRefCount相关的代码(sgen选项)
  • 删除与"Runtime.Arch"相关的检查和分支
  • 删除UI线程检查的检查(如果您继承自UIKit);以及
  • 我们在未来添加的任何未来优化:-)

EDIT:启用链接器的另一个原因是它删除了绑定中多余的(未使用的)方法,从而降低了本机代码需要回调到托管世界的可能性(转换次数越少意味着时间越快)

其他方法更具侵入性,可能需要更改代码以最大限度地减少托管代码和本机代码之间的干扰。例如,有时你可以打电话给

var x = new X (1, 2, 3, 4);

var x = new X ();
x.a = 1;
x.b = 2;
x.c = 3;
x.d = 4;

您可以猜测第一种情况需要更少的转换(并且更快)。如果这样的API不存在,则可以添加,但这应该是一个最少的选择(可能还有其他地方优化会给你带来更大的回报)。

通过查看您的奇怪崩溃错误问题,我注意到cocos2d代码一直在跳回到单点触控领域,因为绑定导出了每个具有objective-c名称的方法的所有单点版本。我想知道你是否可以在没有暴露的情况下重新进行绑定,并获得巨大的速度提升?

除非重写特定的方法,否则您似乎不需要(或者实际上不想要)那些公开的方法——在这种情况下,您可以为重写的方法添加objective-c导出。。。我没有这样做,我不知道这是不是在找麻烦。如果objc端永远不回调,除非你有自定义代码,否则情况似乎会更好。

很想听听poupou或其他xamarin的人对此的评论!