繁体   English   中英

在OpenMP C ++中并行化许多嵌套的for循环

[英]Parallelizing many nested for loops in openMP c++

嗨,我是C ++的新手,我制作了一个可以运行的代码,但是它很慢,因为有许多嵌套的for循环,我想由任何能指导我的人通过openmp来加快速度。 我试图IP循环之前使用“ 的#pragma OMP水货 ”这个循环中我把它圈之前使用“ 的#pragma OMP并行的 ”,但它不工作

    #pragma omp parallel
    for(int ip=0; ip !=nparticle; ip++){
        inf14>>r>>xp>>yp>>zp;
        zp/=sqrt(gamma2);
        counter++;
        double para[7]={0,0,Vz,x0-xp,y0-yp,z0-zp,0};
        if(ip>=0 && ip<=43){
             #pragma omp parallel for
             for(int it=0;it<NT;it++){  
             para[6]=PosT[it];
                for(int ix=0;ix<NumX;ix++){
                    para[3]=PosX[ix]-xp;
                    for(int iy=0;iy<NumY;iy++){
                        para[4]=PosY[iy]-yp;
                        for(int iz=0;iz<NumZ;iz++){
                            para[5]=PosZ[iz]-zp;
                            int position=it*NumX*NumY*NumZ+ix*NumY*NumZ+iy*NumZ+iz;
                            rotation(para,&Field[3*position]);
                            MagX[position] +=chg*Field[3*position];
                            MagY[position] +=chg*Field[3*position+1];
                            MagZ[position] +=chg*Field[3*position+2];
                        }   
                    }
                }
            }   
        }
    }enter code here

而且我的旋转功能还具有无限积分的循环,如下所示

for(int i=1;;i++){
    gsl_integration_qag(&F, 10*i, 10*i+10, 1.0e-8, 1.0e-8, 100, 2, w, &temp, &error);
    result+=temp;
    if(abs(temp/result)<ACCURACY){
        break;
    }
}

我也在使用gsl库。 那么如何加快该过程或如何制作openmp?

不要在另一个并行编译指示中设置并行编译指示。 您可能会在计算机开销上创建过多的线程,无法处理。 我将在外部循环中建立并行化(如果足够大的话):

#pragma omp parallel for
    for(int ip=0; ip !=nparticle; ip++)

还要确保线程之间没有任何竞争条件 (例如RAW)。

忠告:如果您没有获得很大的提速,那么一个好的做法是按块而不是仅按一个增量进行迭代。 例如:

int num_threads = 1;
#pragma omp parallel
{
#pragma omp single
    {
        num_threads = omp_get_num_threads();
    }
}
int chunkSize = 20; //Define your own chunk here
for (int position = 0; position < total; position+=(chunkSize*num_threads)) {
    int endOfChunk = position + (chunkSize*num_threads);
    #pragma omp parallel for
    for(int ip = position; ip < endOfChunk ; ip += chunkSize) {
        //Code
    }
}

如果没有循环间的依赖性,则可以使用collapse关键字将多个循环完全并行化。 例:

void scale( int N, int M, float A[N][M], float B[N][M], float alpha ) {
  #pragma omp for collapse(2)
  for( int i = 0; i < N; i++ ) {
    for( int j = 0; j < M; j++ ) {
      A[i][j] = alpha * B[i][j];
    }
  }
}

我建议您检查一下OpenMP C / C ++备忘单(PDF) ,其中包含有关循环并行化的所有规范。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM