2

mex ファイルを使用して、基本的な openmp 並列化コードをテストしています。問題は、2 つのスレッドで実行するように指示したにもかかわらず、1 つのスレッドしか実行していないように見えることです。コードは次のとおりです。

#include "mex.h"
#include "omp.h"

#include <iostream>


void mexFunction(int nlhs, mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    using namespace std;
    #define x_out plhs[0]
    #define x_in prhs[0]

    double *x;
    double y;
    x_out=mxCreateDoubleMatrix(1,1,mxREAL);
    x=mxGetPr(x_out);
    y=mxGetScalar(x_in);

    x[0]=y;    
    omp_set_num_threads(2);
    int Nthreads=omp_get_num_threads();
    cout<<Nthreads<<"\n";
    #pragma omp parallel
    {
        int ithread=omp_get_thread_num();

        #pragma omp for
                for (int i=0;i<10;i++)
                    cout<<"Hello! " <<i<<"\n";
    }
    return;
}

次のコンパイル行を使用します-

mex -v paralletestmex.cpp CC=g++ CFLAGS="\$CFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp"

詳細な説明では fopenmp フラグが表示されるので、並列になるようにコンパイルしていると思います。

私が得る出力は -

1
Hello! 0
Hello! 1
Hello! 2
Hello! 3
Hello! 4
Hello! 5
Hello! 6
Hello! 7
Hello! 8
Hello! 9

何らかの理由で、1 つのスレッドのみが作成されていることを示しています。これは、より複雑なコードで直面している問題の簡単なテストです。これを mex を使用せずにプレーンな C++ ファイルとして実行すると、同じコードが正常に動作するように見えます。

どんな助けでも大歓迎です。ありがとうございました!シッダールス

4

2 に答える 2

3

これは非常によくある間違いですomp_get_num_threads()。現在のチームのスレッド数を返します。parallel定義上、OpenMP プログラムは並列領域の外側では単一のスレッド (マスター スレッド) のみで実行されるため、領域外で呼び出された場合は常に 1 を返します。

への補完的な呼び出しomp_set_num_threads()omp_get_max_threads().

omp_set_num_threads()また、モジュールやライブラリ関数の作成に関しては、呼び出しは非常に悪いプログラミング手法であることに注意してください。その理由は、後続のすべての並列領域のスレッド数が修正されるため、他のコードに影響を与える可能性があるためです。それを行うためのより良い方法は、次のnum_threads句を使用することです。

#pragma omp parallel num_threads(2)
{
   // ...
}
于 2013-10-29T08:42:43.300 に答える
2

OK、かなりの調査を行った結果、mexopts.sh ファイルの CXXOPTIMFLAGS も変更する必要があることがわかりました。だから私が追加したコンパイル行に:

CXXOPTIMFLAGS="\$CXXOPTIMFLAGS -fopenmp" 

そして、それは仕事をしているようです。

ご助力いただきありがとうございます!

于 2013-10-29T20:20:14.947 に答える