【问题标题】:Poor Perfomance - Android & JNI (C++ image processing with OpenCV)性能不佳 - Android 和 JNI(使用 OpenCV 进行 C++ 图像处理)
【发布时间】:2013-09-20 18:27:21
【问题描述】:

我有一个在 Android 上运行的应用程序,它通过 JNI 接口与 C++ 代码通信。在 C++ 代码中,我正在使用 OpenCV 进行一些硬图像处理。

例如,让“硬处理”需要 40 秒。在 Morotola Milestone 1 或三星 S3 mini 上也需要同样的时间。

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

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

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

我没有发布代码,因为它非常广泛。任何帮助都会非常感激。

【问题讨论】:

  • 桌面处理器比移动处理器快很多。 4 到 5 次听起来很合理。

标签: android performance opencv image-processing jvm


【解决方案1】:

正如@zapl 所提到的,只有 4 到 5 倍的速度是您最初应该期望的。但是,有一些事情需要优化:

  1. 您可以对“痛苦”循环代码块进行基准测试,并比在 NEON 中重写。 NEON intrinsics 应该比未优化的 c/c++ 代码快 2-4 倍。 NEON assembly 通常比 intrinsics 更快,但更难编写。

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

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

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

例如:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多