1

ヘルウー、

スレッド化しようとしているかなり大きなプログラムがあります。これまでのところ、これは成功しており、基本はすべて意図したとおりに機能しています。

私は今、ネストされたモードでカスケードスレッドを使っていくつかの凝った仕事をしたいと思っています. 基本的には、メインの並列領域で下位の並列領域の空きスレッドを使用する必要があります。

現在のシステムを詳しく説明すると、メインの並列領域は 10 個のスレッドを開始します。コアが 12 個あるので、さらに 2 つのスレッドを使用できます。負荷の高いコンピューティングが発生する 2 番目の並列領域があり、最初の 2 つのスレッドがこのポイントに到達して、そこでそれぞれ 2 つのスレッドを持つ新しいチームを開始する必要があります。これ以降、下位の並列領域へのすべての新しいエントリは、シリアルで続行されます。

したがって、これは次のようになります。
メイン領域: 10 個のスレッドが開始されました。
下の領域: 2 つの新しいスレッドが開始されました。

スレッド 1: 下部領域に 2 つのスレッド。
スレッド 2: 下部領域に 2 つのスレッド。
スレッド 3-10: 下部領域に 1 つのスレッド。

これらの数値は、私の状況を明確に説明するためのものであり、プログラムが動作する絶対的かつ唯一のケースではないことに注意してください.

コード:

main() {
    ...
    ...
    omp_set_num_threads(n);
    omp_set_dynamic(x);

    #pragma omp parallel
    {
        #pragma omp for
        for (int i = 0; i < iterations; i++) {
            ...
            Compute();
            ...
        }
    }
}    

そしてコンピュートで

bool Compute() {
    ...
    float nThreads = omp_get_thread_limit() - omp_get_num_threads();
    nThreads = ceil(nThreads / omp_get_num_threads());
    omp_set_num_threads((int)nThreads);
    #pragma omp parallel
    {
        ...
        #pragma omp for
        for (int i = 0; i < nReductSize; i++) {
            ...
        }
    }
}

さて、私の問題は、プログラム全体の上限 (つまり OMP_THREAD_LIMIT) の設定がプログラムの外部からしか機能しないことです。使用する

export OMP_THREAD_LIMIT=5  

bashコマンドラインからうまく機能します。でも社内でやりたい。これまでのところ、私は試しました

putenv("OMP_THREAD_LIMIT=12");
setenv("OMP_THREAD_LIMIT", "12", 1);

しかし、omp_get_thread_limit() または getenv("OMP_THREAD_LIMIT") を呼び出すと、おかしな戻り値が返されます。export で変数を設定しても、getenv("OMP_THREAD_LIMIT"); を呼び出します。0 を返します
。ですから、これについてあなたの助けを求めたいと思います: 実行時に OMP_THREAD_LIMIT を適切に設定するにはどうすればよいですか?

これは、スレッドのデフォルトを設定するメイン関数です。スレッド化が発生する前に実行されます。

#ifdef _OPENMP
    const char *name = "OMP_THREAD_LIMIT";
    const char *value = "5";
    int overwrite = 1;
    int success = setenv(name, value, overwrite);
    cout << "Var set (0 is success): " << success << endl;
#endif

ああ、 setenv は変数の設定に成功したことを報告します。

コンパイラーは
gcc44 (GCC) 4.4.7 20120313 (Red Hat 4.4.7-1) と言っています

フラグ
CCFLAGS = -c -O0 -fopenmp -g -msse -msse2 -msse3 -mfpmath=sse -std=c++0x

OpenMP のバージョンは 3.0 です。

4

3 に答える 3

2

これは OpenMP の正しい実装であり、プログラム内からの環境の変更を無視します。OpenMP 3.1 Standard の 159 ページに記載されているとおり:

プログラムが開始された後の環境変数の変更は、プログラム自体によって変更されたとしても、OpenMP 実装によって無視されます。

あなたはこの段落で述べられていることを正確に行っています。

OpenMP では、関数を介してのみそのようなパラメーターを変更できますomp_set_*が、thread-limit-var ICV にはそのような関数はありません。

ただし、一部の ICV の設定は、適切なディレクティブ句または OpenMP API ルーチンを使用して、OpenMP プログラムの実行中に変更できます。

num_threads句を使用#pragma omp parallelして、目的を達成できると思います。

于 2013-09-06T12:53:24.510 に答える
2

OMP_THREAD_LIMITプログラムの起動後は、 (またはその他のOMP_*環境変数)を使用して OpenMP の動作を変更することはできません。これらはユーザーが使用するためのものです。プログラムを設定してから呼び出すスクリプトを使用して、ユーザーにプログラムを呼び出させることもできますOMP_THREAD_LIMITが、この場合はおそらくそれを行う必要はありません。

OMP_NUM_THREADSomp_set_num_threads、およびnum_threads句は、通常、領域で動作するスレッドの数を設定するために使用されます。

于 2013-09-07T01:58:46.507 に答える