性能差 - Android& JNI(使用OpenCV进行C ++图像处理)

时间:2013-09-16 14:43:35

标签: android performance opencv image-processing jvm

我在 Android 上运行了一个应用,它通过 JNI 界面与 C ++ 代码进行通信。在C ++代码中,我正在使用 OpenCV 进行一些硬图像处理。

例如,进行“硬处理”需要40秒。在Morotola Milestone 1或Samsung S3 mini中需要相同的时间。

我还在2台笔记本电脑上进行了一些测试。在这种情况下,Java App通过JNI与exaclty相同的C ++代码进行通信。如果我在华硕笔记本电脑(AMD E-450处理器)或带有4 GB RAM的Bangho笔记本电脑(英特尔酷睿i5)上运行应用程序,我会在几秒钟内得到相同的结果。 (注意:使用笔记本电脑进行处理的速度要快4到5倍)

我现在有点失望。问题是:

是否有办法充分利用处理器?(我知道我可以更改笔记本电脑中JVM的内存设置,但它似乎不是内存问题)

我不会发布代码,因为这是非常慷慨的。任何帮助都会非常准确。

1 个答案:

答案 0 :(得分:0)

正如@zapl所提到的那样,首先你应该期待的只有4到5倍。但是,有一些事情需要优化:

  1. 您可以对'pain'循环代码块进行基准测试,然后重写,而不是在NEON中。 NEON 内在函数应该比未经优化的c / c ++代码快2-4倍。 NEON 汇编通常比内在函数更快,但更难写。

  2. 使用最新的GCC 4.7并启用GCC的'循环展开'和'循环矢量化'(不是100%确定GCC会为ARM平台实现循环矢量化)。

  3. 使用多线程(C ++ 11)。几乎所有移动处理器都有多个核心。在四核上运行比在单核上运行快2-3.5倍。

  4. 通过在循环外移动if语句,帮助CPU的分支预测器更好地判断接下来要处理的内容。

  5. 例如:

    for(int i = 0; i < total; i++) {
    if (i < middle) 
      // first part
    else
      // second part
    }
    

    替换为:

    for(int i = 0; i < middle; i++)
      // first part
    
    for(int i = middle; i < total; i++)
      // second part