1

私はOpenMPを初めて使用するので、これは非常に基本的なことかもしれません。私は機能を持っています:

void do_calc(int input1[], int input2[], int results[]);

これで、関数は計算中に変更input1[]されますが、それでも別の反復に使用でき(さまざまな方法で並べ替えられます)、input2[]反復ごとに異なり、関数は結果をに格納しますresults[]

プログラムの1つのスレッドバージョンでは、さまざまなを繰り返し処理しinput2[]ます。並列バージョンでは、これを試します。

#pragma omp parallel for reduction (+:counter) schedule(static) private (i,j)
for (i = 0; i < NUMITER ; i++){
    int tempinput1[1000];
    int tempresults[1000];
    int tempinput2[5] = derive_input_from_i(i, input2[]);
    array_copy(input, tempinput);
    do_calc(tempinput, tempinput2, tempresults);
    for (j = 0; j < 1000; j++)
        counter += tempresults[i] //simplified 
}

tempinputこのコードは機能しますが、すべての反復に入力をコピーしており、スレッドごとに1つのコピーしか必要ないため、非常に非効率的です。このコピーは、その後のdo_calc呼び出しで再利用できます。私がしたいのはこれです:

#do this only once for every thread worker:
array_copy(input, tempinput);

次に、スレッドにtempinput、将来の反復のために保存するように指示します。OpenMPでそれを行うにはどうすればよいですか?

その他のパフォーマンスの問題:

a)デュアル/クアッド/オクタルコアプロセッサで動作するコードが必要で、OpenMPにスレッドワーカーの数を決定させ、それらすべてに対して入力を1回コピーします。

b)私のアルゴリズムinput[]は、前の反復でソートすることでメリットがあります(同様のiの場合、キーがわずかに変更されるため、次のソートが高速になります)。したがって、反復回数がスレッド間で均等に分割され、スレッド1が0 ... NUMITER/n部分を取得しないようにします。反復の、スレッド番号2の取得NUMITER/n ... 2*NUMITER/nなど。

b)それほど重要ではありませんが、持っていると非常にクールです:)

(私はVisual Studio 2010を使用しており、OpenMP 2.0バージョンを使用しています)

4

0 に答える 0