2014-09-03 71 views
2

我一直在寻找解决方案至少2天没有成功,所以作为我最后的希望,我决定在这里问它。Android NDK vs iOS - 性能问题

在这里,我们有一个使用OpenCV的C++代码库,我们想要在iOS和Android上运行。事实证明,整个事情在Android上运行速度较慢,我找不到原因。分析后,我们知道调用C++代码的方法是两个平台上完全相同的问题。在Android(三星Galaxy S4)上,需要140-150毫秒才能在iOS(iPhone 5)上执行,而在70毫秒以下。 我读过一些关于优化本机代码和使用不同local_cflags的文章,但似乎没有帮助。

这是需要承认的事实还是有解决方案? 预先感谢您,麦克

+0

这是两个不同的CPU。性能差异并不大,而高端品牌则更快。我看起来并不奇怪。请注意,Android手机会更慢;一些中国淘汰品可能会慢10倍。 – MSalters 2014-09-03 10:18:39

+0

确实如此,但Galaxy S4在规格上拥有更好的CPU。看起来没关系。 – arrafutott 2014-09-03 10:30:28

+1

确保你使用armeabi-v7a版本,不仅是一个普通的armeabi版本。普通的armeabi版本不使用FPU,因此如果代码使用大量的浮动,性能方面的表现会非常有限。 (对于整数运算,差异不应该太大。) – mstorsjo 2014-09-03 10:59:25

回答

3

您的经验与我的关系很好。在(在我的案件中的Nexus 4)使用OpenCV的iOS和Android上我的经验:

  1. Android是一般速度较慢,如果你只使用单线程代码。 Apple CPU核心比我在Android手机上测试过的任何核心都快(请参阅在线提供的许多手机评论),而最新的Android手机拥有4个或更多核心。在iOS上,OpenCV使用GCD并行运行一些算法,但在Android上它不使用OpenMP(这是替代方法,但只适用于GCC 4.x,而不是Clang)。可悲的是,在主线程之外使用OpenMP是一种痛苦。 This bug仍然存在于NDK的r10中,因此无论是使用补丁重新编译工具链,还是卡在主线程中,这对于大量计算来说都不是最佳选择。

  2. Android上的OpenCV默认使用Thumb指令进行编译,而Thumb指令较慢。我建议重新编译设置ARM模式ON和NEON。

  3. Autovectorization标志。如果您在NDK上使用GCC,则必须使用-O3,再加上-funsafe-math-optimizations以启用NEON的自动矢量化。

  4. 限制CPU频率。我的Nexus 4似乎比iOS更热情地节制CPU频率。我们已经看到在iOS上非常稳定的时间运行Android代码的时间大幅度变化,我们能想到的唯一原因是CPU频率。 Renderscript(请参阅this answer)最大化CPU频率,但电池寿命将受损(并且您必须重写代码)。

+1

某些原始设备制造商(例如Qualcomm)对于CPU节流问题非常积极。在测试运行时,您可以通过不断在屏幕上拖动手指来判断是否存在问题 - 该算法的一部分就是在检测到触摸更新时保持高时钟,以便设备在交互时感觉响应。它也可能值得研究在r9b中发生的硬性浮动更改(http://stackoverflow.com/questions/3004915/getting-hardware-floating-point-with-android-ndk),尽管我怀疑它会得到你超过10%左右。 – fadden 2014-09-03 15:24:15

+0

我在几个网站上看过霓虹灯,他们说使用不同的cflags,但它似乎没有工作。我错过了什么吗?我是否必须更改我的代码才能获得霓虹灯的提升? 我忘了写C++代码使用4个线程,所以1)可能没有帮助。 2)和3)带回了希望,虽然我已经添加了-O3标志。 所以问题是霓虹灯是如何工作的? – arrafutott 2014-09-04 08:58:37

+0

特别是在不知道代码的情况下,很难说出为什么代码更慢。你有没有做过任何分析?哪部分最慢? NEON相当于x86机器上的SSE/AVX。这意味着如果编译器没有为你编码你的代码,你必须自己做,或者使用一个已经有NEON实现的库。 – user1906 2014-09-05 00:27:37