2015-02-17 89 views
2

我知道OpenMP包含在NDK中(使用示例在這裏:http://recursify.com/blog/2013/08/09/openmp-on-android)。我已經完成了它在該頁面上所說的內容,但是當我使用:#pragma omp for對掃描矢量的簡單for循環時,該應用程序與着名的「致命信號11」崩潰。Android OpenCV並行化循環

我在這裏錯過了什麼?順便說一句,我使用了一個來自Android示例的修改示例,它是Tutorial 2 Mixed Processing。我所需要的是並行化(多線程)一些for循環,並嵌套用於使用OpenCV時jni C++文件中的循環。

任何幫助/建議表示讚賞!

編輯:示例代碼添加:

#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 謝謝!

+0

很難回答沒有代碼 – 2015-02-17 22:02:50

+0

好吧,樣本添加,我的代碼是基於這個:http://www.slideshare。net/noritsuna/how-to-use-openmp-on-native-activity。我使用OpenCV,我在我的jni文件中包含了,並且它與致命的信號11一起崩潰...我也嘗試過使用單個for循環(或使用if語句)並添加:pragma omp parallel ..仍然崩潰! – Razvan 2015-02-17 22:15:28

回答

1

我認爲這是GOMP中的一個已知問題,請參閱Bug 42616Bug 52738
這是關於如果您嘗試使用OpenMP指令或函數在非主線程的應用程序會崩潰,可以追溯到gomp_thread()功能(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標誌設置,並有一個全局變量用來跟蹤每個線程的狀態,
  • 否則線程本地數據將通過功能pthread_setspecific管理。

在不支持這樣HAVE_TLS將不被限定的線程本地存儲(在__thread關鍵字)NDKs的早期版本,因此pthread_setspecific將被使用。
備註:我不確定在NDK的最新版本中是否支持__thread,但是here可以閱讀關於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 

但是,當應用程序獨立地創建一個線程,該線程的特定數據ISN沒有設置,所以gomp_thread()函數返回NULL。這會導致崩潰,並且這在支持TLS時不成問題,因爲使用的全局變量將始終可用

我記得這個問題已被修復android-ndk-r10d,但它只適用於後臺進程(無Java )。這意味着當您啓用OpenMP並從JNI創建本地線程(從Java Android調用時),那麼您的應用程序將會崩潰。