2016-04-04 165 views
1

我正在實現一種使用強制執行的計算圖形佈局的算法。我想添加OpenMP指令來加速一些循環。在閱讀了一些課程之後,根據我的理解,我添加了一些OpenMP指令。該代碼已編譯,但不會返回與順序版本相同的結果。OpenMP:在while循環中並行化循環

我想知道你是否會善待我的代碼,並幫我弄清楚我的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; 
    } 

預先感謝您提供的任何幫助!

回答

0

您在您的代碼中有數據競賽,例如,在做maxmove = nmove;energy += nforce2;時。在任何多線程代碼中,直到您使用原子訪問(#pragma omp atomic read/write/update)或直到您明確同步對此類變量的訪問(臨界區段,鎖定)時,才能寫入線程共享的變量。首先閱讀關於OpenMP的一些教程,代碼中存在更多問題,例如

if(nmove > maxmove) maxmove = nmove; 

即使使用atomics,您也必須使用所謂的比較 - 交換原子操作來解決此問題。更好的解決方案是讓每個線程計算其局部最大值,然後將其減小到全局最大值。