2017-10-19 11 views
1

私は2つのグループのスレッドを持っています.1つのグループはn個のスレッドで実行され、もう1つのグループはm個のスレッドによって実行されます。私は、そのグループは、最初の1つの開始、同時にそれらを開始したいが、私が取得することで、グループ2異なるスレッド機能を持つ2つのスレッドチームを同時に開始するにはどうすればよいですか?

//group 1 
#pragma omp parallel num_threads(n) 
{ 
    #pragma omp for 
    for (int i = 0; i < n; i++) { 
     function1(i); 
    } 
} 
//group 2 
#pragma omp parallel num_threads(m) 
{ 
    #pragma omp for 
    for (int i = 0; i < m; i++) { 
     function2(i); 
    } 
} 

は私が手出力は次のようになります。

function1 is called 
function1 is called 
function1 is called 
... 
n 
function2 is called 
... 
m 

私は期待して出力(単にランダムな例):

function2 is called 
function2 is called 
function1 is called 
function2 is called 
function1 is called 
... 
+0

しかない場合には、あなたが何をするのかを指定できるようにするいくつかのコンストラクトがありました。それは同時にそれらをすべて行いました。何らかの並列ループを使用することができました。 –

+0

これは、あなたのOSが使用しているスケジューラのタイムスライスや、複数のコアとたくさんのものを使用している場合、おそらく処理したくないものに大きく依存することになります。なぜあなたはそれをしたいのですか? –

答えて

2

あなたの例では、あなたが経験する動作が2つのparallel領域を順次次々に作成されているので、1が期待する正確に何です。

parallel forコンストラクトを使用するアプローチを堅持したい場合は、別のparallelコンストラクトに囲み、ネストされた並列処理も許可する必要があります。それは例えば、これを与えることができる:

#include <stdio.h> 
#include <omp.h> 
#include <unistd.h> 

void function1(int i) { 
    printf("Function1(%d)\n", i); 
    usleep((i * 1237 + 8765) % 9797); 
} 

void function2(int i) { 
    printf("Function2(%d)\n", i); 
    usleep((i * 7321 + 5678) % 10903); 
} 

int main() { 

    int n = 10, m = 5; 
    omp_set_nested(1); 

    #pragma omp parallel sections num_threads(2) 
    { 
     #pragma omp section 
     #pragma omp parallel for num_threads(n) 
     for (int i = 0; i < n; i++) 
      function1(i); 
     #pragma omp section 
     #pragma omp parallel for num_threads(m) 
     for (int i = 0; i < m; i++) 
      function2(i); 
    } 

    return 0; 
} 

NB:私は関数内いくつかの擬似ランダム待ち時間を追加しましたが、それ以外の場合は、返却の一部の遅延を許容するために呼び出して、マングルされた出力を見ての可能性は非常にスリムです。

私のクアッドコアマシンで

、これは(例えば)私を与える:

~/tmp$ gcc -fopenmp pools.c 
~/tmp$ ./a.out 
Function2(2) 
Function1(5) 
Function1(1) 
Function2(1) 
Function2(0) 
Function1(0) 
Function1(3) 
Function1(4) 
Function1(6) 
Function1(9) 
Function1(7) 
Function2(4) 
Function1(2) 
Function1(8) 
Function2(3) 

だからこれはあなたの直接の質問に答えるが、私は最初のアプローチは、最も適切なものではないかもしれないという気持ちを持っています。 taskの構造を見ていることを確実に検討する必要があります。これは達成したいことにはるかに適しているからです。

1

ジルの答えは良いですが、私はいくつかの余分なアイデアをスローしたいと思います:あなたは関数へのスレッドから1 1へのマッピングを持っているので

、非常に短いソリューションがあります:

#pragma omp parallel number_threads(n + m) 
{ 
    assert(omp_get_num_threads() == n + m); 
    auto me = omp_get_thread_num(); 
    if (me < n) function1(me); 
    else function2(me - n); 
} 

- いずれにしても、私は慎重を勧めます。これは、コア(オーバーサブスクリプション)よりも多くのスレッドを持っているパフォーマンスの面で非常に危険なことができ、そしてかなりのOpenMPにスレッド数の選択肢を残して、そしてネスティングない単純な解決策はまだあり:

#pragma omp parallel for 
for (int nm = 0; nm < n + m; nm++) { 
    if (nm < n) function1(nm); 
    else function2(nm - n); 
} 
関連する問題