Android OpenCV 并行化循环

2024-04-09

我知道 OpenMP 包含在 NDK 中(使用示例如下:http://recursify.com/blog/2013/08/09/openmp-on-android http://recursify.com/blog/2013/08/09/openmp-on-android)。我已经按照该页面上的说明进行操作,但是当我使用时:#pragma omp for在扫描向量的简单 for 循环中,应用程序因著名的“致命信号 11”而崩溃。

我在这里缺少什么?顺便说一句,我使用了 Android 示例中的修改示例,它是教程 2 混合处理。我想要的只是在使用 OpenCV 时并行化(多线程)jni c++ 文件中的一些 for 循环和嵌套 for 循环。

任何帮助/建议表示赞赏!

编辑:添加示例代码:

#pragma omp parallel for
Mat tmp(iheight, iwidth, CV_8UC1);
for (int x = 0; x < iheight; x++) {
    for (int y = 0; y < iwidth; y++) {
        int value = (int) buffer[x * iwidth + y];
        tmp.at<uchar>(x, y) = value;
    }
}

基于此:http://www.slideshare.net/noritsuna/how-to-use-openmp-on-native-activity http://www.slideshare.net/noritsuna/how-to-use-openmp-on-native-activity Thanks!


我认为这是 GOMP 中的一个已知问题,请参阅错误 42616 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42616 and 错误 52738 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52738.
这是关于如果您尝试在非主线程上使用 OpenMP 指令或函数,您的应用程序将会崩溃,并且可以追溯到gomp_thread()功能 (see libgomp/libgomp.h https://android.googlesource.com/toolchain/gcc/+/master/gcc-4.6/libgomp/libgomp.h@第362行和第368行)返回NULL对于您创建的线程:

#ifdef HAVE_TLS
    extern __thread struct gomp_thread gomp_tls_data;
    static inline struct gomp_thread *gomp_thread (void)
    {
      return &gomp_tls_data;
    }
#else
    extern pthread_key_t gomp_tls_key;
    static inline struct gomp_thread *gomp_thread (void)
    {
      return pthread_getspecific (gomp_tls_key);
    }
#endif

正如您所看到的,GOMP 根据线程本地存储 (TLS) 是否可用而使用不同的实现。

  • 如果可用的话HAVE_TLS设置了flag,并使用一个全局变量来跟踪每个线程的状态,
  • 否则,线程本地数据将通过该函数进行管理pthread_setspecific.

在 NDK 的早期版本中,线程本地存储(__thread关键字)不受支持,所以HAVE_TLS不会被定义,因此pthread_setspecific将会被使用。
备注:我不确定是否__threadNDK 的最新版本是否支持,但是here https://stackoverflow.com/questions/27191214/no-luck-compiling-thread-using-ndk-clang-3-4-3-5您可以阅读有关 Android TLS 的相同答案。

当 GOMP 创建工作线程时,它会在函数中设置线程特定数据gomp_thread_start()(第 72 行):

#ifdef HAVE_TLS
    thr = &gomp_tls_data;
#else
    struct gomp_thread local_thr;
    thr = &local_thr;
    pthread_setspecific (gomp_tls_key, thr);
#endif

但是,当应用程序独立创建线程时,不会设置线程特定数据,因此gomp_thread()函数返回NULL。这会导致崩溃,但在支持 TLS 时这不是问题,因为使用的全局变量始终可用

我记得这个问题已经解决了android-ndk-r10d,但它仅适用于后台进程(无 Java)。这意味着当您启用 OpenMP 并从 JNI(从 Java Android 中调用)创建本机线程时,您的应用程序将仍然崩溃。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android OpenCV 并行化循环 的相关文章

随机推荐