【问题标题】:Codename One iOS 64-bit performance代号一 iOS 64 位性能
【发布时间】:2021-06-06 18:53:06
【问题描述】:

我的应用程序包含一个多线程引擎,该引擎可以进行类似于国际象棋的游戏。 它对 64 位字执行大量按位运算(移位和等)。 在 PC 上,64 位版本比 32 位版本快得多,而在最近的手机/平板电脑上,您会期望相同。 下表包含一些测试结果(最好的结果是 100,越少意味着越慢)。 基准包括并行添加数字 1 到 2 亿。我验证了 4 线程比 2 或 1 快。

hardware           os      build         threads benchmark search task
----------------------------------------------------------------------
MacBook            Windows 64-bit JVM       4          100         100
MacBook            Windows CN1 Simulator    4          100          42
iPhone X           iOS     debug armv7      4           14           2
iPhone X           iOS     debug arm64      4           14           2
Samsung Tab A 10.1 Android debug            4            8           1
Samsung Tab A 10.1 Android release          4           10           7

观察:

  1. 在 MacBook 上,搜索任务在模拟器中的执行速度是普通 64 位 JVM 的两倍多。 大概这是因为没有(本机)对 Long.bitCount() 和 Long.numberOfTrailingZeros() 函数的支持, 我不得不用(较慢的)代码替换它。问题:有没有办法改善这一点?
  2. iPhone X armv7 和 arm64 版本之间没有区别。这怎么可能? (我尝试删除该应用程序并 在安装arm64版本之前重启手机。当前的 AppStore 版本是 32 位 IIRC。)
  3. Android 发行版在搜索任务上的表现比调试版好得多:快 7 倍!

在三星 Tab 上表现令人满意,在 iPhone X 上我会说它低于标准。 CPU 比较(iPhone X:64 位 6 核 @ 2.39 和 1.42 GHz,三星 Tab A 10.1:64 位 8 核 @ 1.6 GHz) iPhone X 不应该慢 3.5 倍(得分 2 vs 7)。

可以肯定的是,我使用 MacOS 的“文件”命令查看了 iOS arm64 调试构建 ipa,它显示:Mach-0 64 位可执行文件。

所以我很困惑:为什么 arm64 在我的 iPhone X 上构建速度不快?

我在某处读到“iPhone X 的处理器比最新的 MacBook Pro 更强大”(2017 年),这是不对的。 (我认为我的 MacBook 是 2015 年的。)

顺便说一句,我使用一个外部库 Device 来检测设备是否是 iPhone X,我尝试使用 ios.add_libs=ExternalAccessory.framework。

编辑

有关 iOS ipa 文件的更多信息:

32 位 Main.ipa 7.3 MB 文件:Mach-0 可执行 arm

64 位 Main.ipa 7.1 MB 文件:Mach-0 64 位可执行文件

在 2012 iPad 4 上仅安装 32 位 ipa。 (0-100 范围内的搜索任务性能为 0.4。) 在 iPhone X 上安装了 32 位和 64 位 ipa,但没有性能差异,这很奇怪。 搜索任务性能为 2.0,与三星 Tab (7.0) 相比较低。

【问题讨论】:

  • 您可能应该考虑使用Metal - 使用 GPU 而不是 CPU,您将获得更好的性能和更低的能耗

标签: ios performance 64-bit codenameone iphone-x


【解决方案1】:

在 MacBook 上,搜索任务的执行速度要慢两倍以上 模拟器与普通的 64 位 JVM 相比。大概这是 因为没有(本机)对 Long.bitCount() 函数的支持 和 Long.numberOfTrailingZeros(),我不得不用 (slower) 替换它 代码。问题:有什么办法可以改善吗?

您可以使用本机接口并将 JavaSE 部分实现为 Long.bitCount()Long.numberOfTrailingZeros()。这将在模拟器上运行得一样快。

另一种方法是实现 Codename One API,该 API 在重要的操作系统上本地执行此操作,并使用模拟作为您不支持的事物的后备。然后向 Codename One 提交 PR。您可以通过使用回退代码修改 CodenameOneImplementation.java 然后更新 JavaSEPort.javaAndroidImplementation.javaIOSImplementation.java 等来做到这一点。

然后您会以某种方式向用户公开这些 API,这通常是通过 Display 进行的,但在这种情况下可能不是理想的用户 API 场所。

iPhone X armv7 和 arm64 构建之间没有区别。 这怎么可能? (我尝试删除应用程序并重新启动 安装arm64版本之前的手机。目前的应用商店 版本是 32 位,IIRC。)

苹果现在需要 64 位,因此我们不再支持没有它的构建。

Android 发布版在搜索任务上的表现比调试版好得多:快 7 倍!

这些事情很难说。它可能是 iOS 不允许的 Android JIT,也可能是我们未能优化的一段代码。我们需要对生成的代码进行微基准测试。

但是,JavaSE JIT 速度惊人,可以围绕我们抛出的任何本机编译基准运行。这不是 AoT VM 可以与之竞争的东西。我们确实有其他优势,例如运行时更一致的行为和更少的打嗝。

【讨论】:

  • 感谢您的回答。我对优化 Long.bitCount() 和 Long.numberOfTrailingZeros() 很感兴趣,但我不明白应该如何实现。我们以 Long.bitCount() 为例,你的第一个选项会是什么样子?
  • 我不确定你所说的“苹果现在需要 64 位,所以我们不再支持没有它的构建”。我对没有 64 位的构建不感兴趣,我对最好的 64 位性能感兴趣。我已经编辑了我的问题,以显示有关 32 位和 64 位版本的更多信息。你同意 iPhone X 的 64 位性能比较差吗? iOS AppStore 构建是否有可能比调试构建更快? (不知道如何测试。)如果你愿意,我可以编译一个有代表性的测试用例进行微基准测试。
  • 您无法在现代 iOS 设备上测试 32 位代码,因此两个结果将始终与 64 位结果相同。是的,在某些情况下性能并不理想。我建议只发送带有“包含源”的构建或使用 ParparVM 源代码来翻译您的字节码 sn-p。然后,您可以查看生成的 C 代码以了解生成的内容以及我们是否可以做得更好。
  • 我创建了一个小型性能测试项目,并按照您所说的查看了生成的 Objective C 代码。我不是这方面的专家,我假设代码稍后会被编译和优化。代码确实提出了一些问题,例如:是否有必要将局部函数变量声明为 volatile?并为每个参数创建一个局部变量,首先为其分配一个零值,然后再分配参数的值?另外,为什么在 AppStore 构建中也有对 __CN1_DEBUG_INFO() 的调用?这会减慢执行速度。您可以对我的性能测试项目感兴趣吗?
  • 是的。请提出问题,我们可以以更有条理的方式进行审查。很多这些东西都被编译器剥离了,所以局部变量主要是为了方便,但不会花费太多。堆栈跟踪工作需要调试信息。它们甚至存在于生产环境中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-27
  • 2011-03-21
  • 2011-12-31
  • 2011-07-21
  • 1970-01-01
  • 2012-02-15
  • 1970-01-01
相关资源
最近更新 更多