粒子ベースのシミュレーションのコードを並列化しようとしていますが、OpenMP ベースのアプローチのパフォーマンスが低下しています。つまり、次のことを意味します。
- Linux ツールを使用して CPU 使用率を表示する
top
と、CPU を実行している OpenMP スレッドの平均使用率は 50% です。 - スレッド数が増えると、速度は約 1.6 倍に収束します。収束は非常に高速です。つまり、2 つのスレッドを使用して 1.5 の速度アップに達しました。
次の疑似コードは、実装されたすべての並列領域の基本テンプレートを示しています。1 つの時間ステップ中に、以下に示すように 5 つの並列領域が実行されることに注意してください。基本的に、粒子に作用する力i < N
は、隣接する粒子のいくつかのフィールド プロパティの関数ですj < NN(i)
。
omp_set_num_threads(ncpu);
#pragma omp parallel shared( quite_a_large_amount_of_readonly_data, force )
{
int i,j,N,NN;
#pragma omp for
for( i=0; i<N; i++ ){ // Looping over all particles
for ( j=0; j<NN(i); j++ ){ // Nested loop over all neighbors of i
// No communtions between threads, atomic regions,
// barriers whatsoever.
force[i] += function(j);
}
}
}
観察されたボトルネックの原因を整理しようとしています。説明のための私の素朴な最初の推測:
前述のように、読み取り専用アクセスのためにスレッド間で共有される大量のメモリがあります。異なるスレッドが同じメモリ位置を同時に読み取ろうとする可能性は十分にあります。これはボトルネックを引き起こしていますか? OpenMP にプライベート コピーを割り当てさせるべきでしょうか?