私は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バージョンを使用しています)