OpenMP Runtime没有加速

时间:2015-07-15 12:46:06

标签: parallel-processing openmp

我正在尝试制作一个函数的并行版本。但是,添加openmp操作程序后应该加快线程数量的增加。它没有发生。我运行程序时也得到不同的结果(输出)。这是我使用的代码。我赞美你的帮助

void simulate(int m, int n, double delt, double eps, double x[], double   y[], double z[], int iter, double xn[], double yn[], double zn[])
{

    double zero = 0.0, one = 1.0, twopi = 6.2831853071795864769252866;
    int i, itest, j,divtest;
    double aux,auy,delt2,delt3,eps2,fx,fy,fz,ftx,fty,ftz,step;

    return if n<5
    if (n < 5) return;

    //initialization
    iter = 0;
    delt2 = 0.5*delt*delt;
    delt3 = delt2*delt2;
    eps2 = eps*eps;

    //initial distribution of points
    auy = zero;
    itest=n+1;
    j = n+2;
    fx = (double)(n);
    x[1] = zero;
    y[1] = zero;
    z[1] = one;

    #pragma omp parallel private(i) {
        #pragma omp for schedule(static) nowait
        for (i=2; i <= n; i++){ 
            step = (double)(i+i-j)/fx;
            auy = fmod(auy+3.6/sqrt(itest*(one-step*step)),twopi);
            aux = sin(auy);
            x[i] = aux*step;
            y[i] = aux*sin(acos(step));
            z[i] = cos(auy);
        }
    }
    // main iteration loop

    while(itest==1){
        iter=iter+1;
        itest=0;
        #pragma omp parallel default(shared) private(i,j){
            #pragma omp for schedule(static) nowait 
            for (i=1; i <= n; i++) {
                // total sum of force vectors
                fx=zero;
                fy=zero;
                fz=zero;

                #pragma omp for schedule(static) 
                    for (j=1; j<=n ; j++) {
                        if (j != i) {
                            aux=pow(x[i]-x[j],2.0)+pow(y[i]-y[j],2.0)+pow(z[i]-z[j],2.0);
                            aux=aux*sqrt(aux);
                            fx=fx+(x[i]-x[j])/aux;
                            fy=fy+(y[i]-y[j])/aux;
                            fz=fz+(z[i]-z[j])/aux;
                         }
                     }

                 // tangential component of force
                 aux=x[i]*fx+y[i]*fy+z[i]*fz;

                 ftx=fx-x[i]*aux;
                 fty=fy-y[i]*aux;
                 ftz=fz-z[i]*aux;

                 aux=ftx*ftx+fty*fty+ftz*ftz;

      #pragma omp flush(itest)
      if (aux > eps2) {
          itest=1;
          aux=sqrt(one-aux*delt3);
          xn[i]=x[i]*aux+ftx*delt2;
          yn[i]=y[i]*aux+fty*delt2;
          zn[i]=z[i]*aux+ftz*delt2;      
      }
  }

  #pragma omp for schedule(static)
  for (i=1; i <= n; i++) {
      x[i]=xn[i];
      y[i]=yn[i];
      z[i]=zn[i];
  }
  }  

  } 
}

1 个答案:

答案 0 :(得分:1)

哟没有加速,因为有很多数据竞赛。 (不同的线程尝试同时写入相同的变量)。这些数据竞争也是您获得的输出错误的原因。 (感谢@ High-Performace-Mark指出这一点)

为简单起见,我建议您开始并行化最内部循环(j)。在那里,您会看到auxfxfyfz变量被不同的线程修改。

对于aux,您可以告诉它这是一个私有变量,并且您可以将f输入表示为减少(它们总结了不同迭代中的所有值):

#pragma omp parallel for private(aux) reduction(+:fx,fy,fz)
for (j=1; j<=n ; j++) {
  if (j != i) {
    aux = pow(x[i]-x[j],2.0)+pow(y[i]-y[j],2.0)+pow(z[i]-z[j],2.0);
    aux *= sqrt(aux);
    fx += (x[i]-x[j])/aux;
    fy += (y[i]-y[j])/aux;
    fz += (z[i]-z[j])/aux;
  }
}