私のコードには、ny*nx 行列内を移動するためのネストされたループを含むメソッドがいくつかあります。プロセスを並列化したかったので、すべてのメソッドで次のようなものを使用しました。
#pragma omp parallel for private(jj,x_e,x_w,y_n,y_s)
for(ii=0;ii<ny;ii++) {
for(jj=0;jj<nx;jj++) {
/* determine indices of axis-direction neighbours
** respecting periodic boundary conditions (wrap around) */
y_n = (ii + 1) % ny;
x_e = (jj + 1) % nx;
y_s = (ii == 0) ? (ii + ny - 1) : (ii - 1);
x_w = (jj == 0) ? (jj + nx - 1) : (jj - 1);
//propagate densities to neighbouring cells, following
tmp[ii *nx + jj].speeds[0] = cells[ii*nx + jj].speeds[0]; /* central cell, */
/* no movement */
tmp[ii *nx + x_e].s[1] = cells[ii*nx + jj].s[1]; /* east */
tmp[y_n*nx + jj].s[2] = cells[ii*nx + jj].s[2]; /* north */
tmp[ii *nx + x_w].s[3] = cells[ii*nx + jj].s[3]; /* west */
tmp[y_s*nx + jj].s[4] = cells[ii*nx + jj].s[4]; /* south */
tmp[y_n*nx + x_e].s[5] = cells[ii*nx + jj].s[5]; /* north-east */
tmp[y_n*nx + x_w].s[6] = cells[ii*nx + jj].s[6]; /* north-west */
tmp[y_s*nx + x_w].s[7] = cells[ii*nx + jj].s[7]; /* south-west */
tmp[y_s*nx + x_e].s[8] = cells[ii*nx + jj].s[8]; /* south-east */
}
}
ただし、このコード (およびその他のコード) は非常に低速です。#pragma ステートメントを修正し、データ構造またはループを書き直して、キャッシュに適したものにし、誤った共有を回避する方法はありますか?
PS: コードは でコンパイルされて-O3
いるため、マイナーな最適化を試みるたびに速度が向上しませんでした。