2016-04-04 29 views
1

Kuvvet yönelimli kullanarak grafik düzenini hesaplamak için bir algoritma uyguluyorum. Bazı döngüleri hızlandırmak için OpenMP direktiflerini eklemek istiyorum. Bazı kursları okuduktan sonra, benim anlayışıma göre bazı OpenMP direktiflerini ekledim. Kod derlenmiştir, ancak sıralı sürümle aynı sonucu döndürmeyin.OpenMP: Bir döngü içinde döngüleri için paralelize

Koduma bakacak ve OpenMP sürümümde neyin ters gittiğini anlamaya yardımcı olacak kadar nazik olmanızı rica ediyorum.

burada arşivini indirin edin: Gördüğünüz gibi http://www.mediafire.com/download/3m42wdiq3v77xbh/drawgraph.zip

, ben parallelize istediğiniz kod kısmıdır:

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

Özellikle hesaplama kaynaklarının sürü tüketir bu iki döngüler:

/* 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; 
    } 

Sağladığınız herhangi bir yardım için şimdiden teşekkür ederiz!

cevap

0

maxmove = nmove; veya energy += nforce2; yaparken Kodunuzdaki, örneğin içinde veri yarışları var. Herhangi bir çok iş parçacıklı kodda, bir atomik erişim (#pragma omp atomic read/write/update) kullanana veya bu tür bir açıklığa erişimi açıkça (kritik bölümler, kilitler) eşitleyene kadar iş parçacıkları tarafından paylaşılan bir değişkene yazamazsınız. OpenMP hakkında bazı eğitici bilgileri okuyun, kodunuzla ilgili daha fazla sorun var, örn.

if(nmove > maxmove) maxmove = nmove; 

bu hat genellikle atomics bile çalışmayacak (eğer bu çözmek için sözde karşılaştırma ve değişimi atom operasyon kullanmak zorunda olacaktır). Burada çok daha iyi bir çözüm, her bir iş parçacığının yerel maksimum değerini hesaplamasına ve daha sonra bunu global bir maksimum değere indirmesine izin vermektir.