OpenMP:在while循环内并行化循环

时间:2016-04-04 07:24:25

标签: c for-loop parallel-processing openmp hpc

我正在实现一种使用强制定向来计算图形布局的算法。我想添加OpenMP指令来加速一些循环。阅读完一些课程后,我根据自己的理解添加了一些OpenMP指令。代码已编译,但不会返回与顺序版本相同的结果。

我想知道你是否愿意查看我的代码并帮助我弄清楚我的OpenMP版本出了什么问题。

请在此下载档案: http://www.mediafire.com/download/3m42wdiq3v77xbh/drawgraph.zip

如您所见,我要并行化的代码部分是:

unsigned long graphLayout(Graph * graph, double * coords, unsigned long maxiter) 

特别是,这两个循环消耗了大量的计算资源:

/* compute repulsive forces (electrical: f=-C.K^2/|xi-xj|.Uij) */      
  for(int j = 0 ; j < graph->nvtxs ; j++) { 
    if(i == j) continue;
    double * _xj = _position+j*DIM;
    double dist = DISTANCE(_xi,_xj);        
    // power used for repulsive force model (standard is 1/r, 1/r^2 works well)
    // double coef = 0.0; -C*K*K/dist;       // power 1/r
     double coef = -C*K*K*K/(dist*dist); // power 1/r^2 
    for(int d = 0 ; d < DIM ; d++) force[d] += coef*(_xj[d]-_xi[d])/dist;
  }

/* compute attractive forces (spring: f=|xi-xj|^2/K.Uij) */
  for(int k = graph->xadj[i] ; k < graph->xadj[i+1] ; k++) {
    int j =  graph->adjncy[k]; /* edge (i,j) */ 
    double * _xj = _position+j*DIM;
    double dist = DISTANCE(_xi,_xj);            
    double coef = dist*dist/K;
    for(int d = 0 ; d < DIM ; d++) force[d] += coef*(_xj[d]-_xi[d])/dist;   
  }

提前感谢您提供任何帮助!

1 个答案:

答案 0 :(得分:1)

您的代码中有数据竞赛,例如,在执行maxmove = nmove;energy += nforce2;时。在任何多线程代码中,在使用原子访问(#pragma omp atomic read/write/update)或直接同步对此类变量的访问(关键部分,锁定)之前,您无法写入线程共享的变量。首先阅读一些关于OpenMP的教程,您的代码存在更多问题,例如

if(nmove > maxmove) maxmove = nmove;

即使使用原子,这条线通常也不会起作用(你必须使用所谓的比较和交换原子操作来解决这个问题)。这里更好的解决方案是让每个线程计算其局部最大值,然后将其减少到全局最大值。