現在、内部ループに結果を保存する必要がある条件で、ループのセットを並列化する高速で信頼性の高い方法を探しています。 コードは3Dグリッド内の膨大なポイントを通過するはずです。このボリューム内のいくつかの点については、別の条件(角度のチェック)をチェックしなければならず、この条件が満たされれば密度を計算する必要があります。Openmpは順序付き出力付きのループをネストしました
これまでのところ、最も速い方法は、すべてのループの外側にある#pragma omp parallel for private (x,y,z) collapse(3)
または最も大きなループであるだけでなく、CPUを集中的に呼び出す機能を呼び出す最も内側のループ(phiInd)の#pragma omp parallel for
でした。
濃度値を内部ループ内の濃度に格納する必要があります。その後、濃度アレイは後に別々に保存される。 私の問題は今、私が設定したスレッドの数によっては、密度の配列が異なる結果になることです。シリアルバージョンと1スレッドだけを持つopenmpの実行結果は同じです。 スレッド数を増やすと、結果は同じポイントになりますが、その結果はシリアルバージョンとは異なります。
私は#pragma omp for ordered
があることを知っていますが、計算が遅すぎます。 ポイント(x、y、z)に基づいて結果を取得しながら、このループを並列化する方法はありますか? 多分もっと明確に:スレッド番号を増やすと結果が変わるのはなぜですか?
double phipoint, Rpoint, zpoint;
double phiplane;
double distphi = 2.0 * M_PI/nPlanes; //set desired distace to phi to assign point to fluxtubeplane
double* densityarr = new double[max_x_steps * max_y_steps * max_z_steps];
for (z = 0; z < max_z_steps; z++) {
for (x = 0; x < max_x_steps; x++) {
for (y = 0; y < max_y_steps; y++) {
double x_center = x * stepSizeGrid - max_x/2;
double y_center = y * stepSizeGrid - max_y/2;
double z_center = z * stepSizeGrid - max_z/2;
cartesianCoordinate* pos = new cartesianCoordinate(x_center, y_center, z_center);
linearToroidalCoordinate* tor = linearToroidal(*pos);
simpleToroidalCoordinate* stc = simpleToroidal(*pos);
phipoint = tor->phi;
if (stc->r <= 0.174/*0.175*/) {//check if point is in vessel
for (int phiInd = 0; phiInd < nPlanes; ++phiInd) {
phiplane = phis[phiInd];
if (abs(phipoint - phiplane) <= distphi) {//find right plane for point
Rpoint = tor->R;
zpoint = tor->z;
densityarr[z * max_y_steps * max_x_steps + x * max_y_steps + y] = TubePlanes[phiInd].getMinDistDensity(Rpoint, zpoint);
}
}
}
delete pos, tor, stc;
}
}
}
ここで 'phipoint' /' phipane'が定義されています。 'densityarr'はどのような型ですか? – Zulan
これらのループの前。 'phipoint'と' phipane'は両方とも二倍です。 'densityarr'はdouble *です。.. ' double phiplane、phipoint; double * densityarr = new double [max_x_steps * max_y_steps * max_z_steps]; ' – LeBo