Android OpenCV parallelize loops

孤者浪人 提交于 2019-12-11 02:52:31

问题


I know that OpenMP is included in NDK (usage example here: http://recursify.com/blog/2013/08/09/openmp-on-android ). I've done what it says on that page but when I use: #pragma omp for on a simple for loop that scans a vector, the app crashes with the famous "fatal signal 11".

What am I missing here? Btw I use a modified example from the Android samples, it's Tutorial 2 Mixed Processing. All I want is to parallelize (multithread) some of the for loops and nested for loops that I have in the jni c++ file while using OpenCV.

Any help/suggestion is appreciated!

Edit: sample code added:

#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;
    }
}

Based on this: http://www.slideshare.net/noritsuna/how-to-use-openmp-on-native-activity Thanks!


回答1:


I think this is a known issue in GOMP, see Bug 42616 and Bug 52738.
It's about your app will crash if you try to use OpenMP directives or functions on a non-main thread, and can be traced back to the gomp_thread() function (see libgomp/libgomp.h @ line 362 and 368) which returns NULL for threads you create:

#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

As you can see GOMP uses different implementation depending on whether or not thread-local storage (TLS) is available.

  • If it is available, then HAVE_TLS flag is set, and a global variable is used to track the state of each thread,
  • Otherwise, thread-local data will be managed via the function pthread_setspecific.

In the earlier version of NDKs the thread-local storage (the __thread keyword) isn't supported so HAVE_TLS won't be defined, therefore pthread_setspecific will be used.
Remark: I'm not sure whether __thread is supported or not in the last version of NDK, but here you can read the same answers about Android TLS.

When GOMP creates a worker thread, it sets up the thread specific data in the function gomp_thread_start() (line 72):

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

But, when the application creates a thread independently, the thread specific data isn't set, and so the gomp_thread() function returns NULL. This causes the crash and this isn't a problem when TLS is supported, since the global variable that's used will always be available

I remember that this issue had been fixed android-ndk-r10d, but it only works with background processes (no Java). It means when you enable OpenMP and create a native thread from JNI (what is called from Java Android) then your app will crash remains.



来源:https://stackoverflow.com/questions/28571874/android-opencv-parallelize-loops

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!