2016-04-13 2 views
3

У меня есть код C++, который использует openMP для параллельной работы.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, я создаю dll с помощью 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. Но я никогда не использовал OpenMP в Windows ... –

ответ

2

Действительно, на вашу текущую проблему ответил @Andrew Henle в комментариях: вам необходимо использовать -fopenmp во время как шагов компиляции, так и ссылки.

Тем не менее, я хотел расширить и сказать, что ваш код as-is представляет собой случай учебника о том, когда следует использовать 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 обрабатывает всю балансировку нагрузки для вас, если у вас есть больше section s, чем потоки.

+0

Спасибо, это очень полезно! – Bob

Смежные вопросы