gpt4 book ai didi

c# - 降低单点触控中 native <-> 托管交互的成本

转载 作者:搜寻专家 更新时间:2023-10-30 20:05:59 24 4
gpt4 key购买 nike

我正在玩一个 native 库,我为此编写了 monotouch(我们现在应该将其命名为 Xamarin.iOS 吗?)绑定(bind)。

重写 C# 中的一些常用方法会导致严重的性能下降,即使函数的核心不执行任何操作或返回 base.X()。 Instruments 确认了问题以及在托管<->本地交互中花费的时间。

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

我遇到的玻璃天花板大约是每秒 50000 次调用。

[更新 2013/02/22]举一些背景或例子,这就是我正在做的。我正在玩 cocos2d 运动学(没有花栗鼠)。为了管理我自己的 Sprite 位置,我必须重写

CGAffineTransform NodeToParentTransform { get; }

bool Dirty { get; }

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

我在降低成本方面的尝试目前取得了部分成功,因为通过将 native 代码更改为具有单个点来覆盖它不会戳到任何属性,我获得了 25% 到 50% 的加速。

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

我的 3500 个 Sprite 现在几乎可以接受 25-30fps,但我仍然想走得更远。而且也不必修补 native 源。

[更新 2013/02/22 2]这是您可以用来测试的示例 https://github.com/StephaneDelcroix/mt-speed .它包含一个过度简化的一阶运动引擎、3501 个主体和 Sprite 。

这里有趣的类是KinematicSprite。代码适用于 cocos2d 的修改版本(包含在 Cocos2D.dll 中)。您可以通过注释掉新的 Dirty 函数并取消注释 NodeToParentTransform 和旧的 Dirty 使其在现有的 cocos2d 和 cocos2d 绑定(bind)上工作。根据 Subclassing bound type in mono touch ,它只适用于设备。我在 iPad mini 上达到 20 到 22.5 fps。

最佳答案

are we supposed to name that Xamarin.iOS now?

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

Or is this a tax to pay when P/Invoking in MT ?

从托管代码和非托管代码转换时,有很多事情要做。 trampolines 负责:编码(marshal)参数和返回值、处理托管异常、处理 native 异常...

您也可能多次进行转换,例如new Managed (); 调用 native init* 调用 (native) setFoo: 回到 (managed) Foo setter(然后返回...给调用者)。

因此,即使每个部分都很快,如果您不执行任何操作(或只调用 base),它仍然会值得注意,因为没有太多的用户时间可以摊销反对。

Is there a way to speed that up, from one side or the other (native or managed) ?

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

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

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

因此,您可能希望在 iOS (ARM) 设备上测量发布版本。

接下来您应该做的是确保启用链接所有程序集(如果您有非 SDK 绑定(bind),例如 Cocos2d)。这不会改变蹦床,但当您调用 base 时,您正在调用绑定(bind)代码。

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

编辑:启用链接器的另一个原因是它删除了绑定(bind)中的额外(未使用)方法 - 使得 native 代码不太可能需要回调到托管世界(和更少的转换意味着更快的时间)

其他方法更具侵入性,可能需要更改代码以尽量减少托管代码和 native 代码之间的冲突。例如。有时你可以打电话

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 不存在,那么可以添加它 - 但这应该是一个最少的选择(可能有其他地方的优化会让你获得更大的返回)。

关于c# - 降低单点触控中 native <-> 托管交互的成本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14985336/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com