2016-04-13 65 views
3

我有一個使用openMP並行運行的C++代碼。OpenMP不會與JNI並行運行

void f(){ 
omp_set_num_threads(3); 
#pragma omp parallel 
{ 
if (omp_get_thread_num() == 0){ 

     // do task 1 

}else if (omp_get_thread_num() == 1){ 

    //do task 2 

}else if (omp_get_thread_num() == 2){ 

    //do task 3 
}} 

我使用SWIG JNI來創建一個DLL並從Java調用此代碼。

System.loadLibrary("model"); 
model.f(); 

它以串行模式運行。當我直接用C++編譯代碼並在命令行中運行時,它會並行運行。

你知道如何解決這個問題嗎?

+0

您是否對命令行和JNI調用相同的二進制文件?或者你編譯不同的二進制文件,命令行的可執行文件和JNI的庫? –

+0

對於JNI,我使用swig和g ++創建一個dll,然後用Java加載它。我不創建二進制文件。 'swig -C++ -java model.i' 'g ++ -c model.cpp model_wrap.cxx -I ...' 'g ++ -shared model.o model_wrap.o -o model.dll -I ... -L ...和一些庫' 但是,對於直接使用C++,我使用g ++編譯器創建一個二進制文件並使用它。 'g ++ model.cpp -o model.exe -I ... -L ...和libraries' – Bob

+0

假設g ++和OpenMP類似於Linux的用法,如果編譯爲'.o',文件使用'-fopenmp'參數到'g ++',但是在鏈接步驟中不要使用'-fopenmp'?我懷疑OpenMP庫沒有被JVM加載。但是我從來沒有在Windows上使用OpenMP .... –

回答

2

的確,您的當前問題由@Andrew Henle在評論中回答:您在編譯和鏈接步驟中都需要使用-fopenmp

但是,我想擴展並說您的代碼是 - 提供了何時使用OpenMP sections的教科書案例。你應該改變你的代碼,以這些語義的優勢:

void f() { 
    omp_set_num_threads(3); 
    #pragma omp parallel sections 
    { 
     #pragma omp section 
     { 
      // do task 1 
     } 
     #pragma omp section 
     { 
      //do task 2 
     } 
     #pragma omp section 
     { 
      //do task 3 
     } 
    } 
} 

這有(一)成爲串行代碼時,你不支持OpenMP,OpenMP的原始信條之一編譯優勢;和(b)輕鬆允許擴展更多的線程和/或更多的線程。如果您擁有比線程更多的section,則OpenMP將爲您處理所有負載平衡。

+0

謝謝,這確實非常有用! – Bob