2012-06-20 40 views
4

我正在使用OpenMP來製作Dijkstra算法的並行版本。我的代碼由兩部分組成。第一部分僅由一個線程(主)執行。這個線程從列表中選擇新的節點。第二部分由其他線程執行。這些線程改變了從源到其他節點的距離。不幸的是,在我的代碼中是錯誤的,因爲許多執行第二部分的線程中的一個突然「消失」了。數據同步可能存在問題,但我不知道在哪裏。如果有人能告訴我我的錯誤在哪裏,我將不勝感激。下面是代碼:Parallel Dijkstra

map<int, int> C; 
map<int, int> S; 
map<int, int> D; 
int init; 
int nu; 
int u; 
int p = 3;//omp_get_num_threads(); 
int d; 
int n = graph->getNodesNum(); 

#pragma omp parallel shared(n, C, d, S, init, nu, u, D, graph, p) num_threads(p) 
{ 
    int myId = omp_get_thread_num(); 
    if (myId == 0) 
    { 
     init = 0; 
     nu = 0; 

     u = to; 
     while (init < p - 1) 
     { 
     } 

     while (u != 0) 
     { 
      S[u] = 1; 
      while (nu < p - 1) 
      { 
      } 
      u = 0; 
      d = INFINITY; 
      for (int i = 1; i <= p - 1; ++i) 
      { 
       int j = C[i]; 
       if ((j != 0) && (D[j] < d)) 
       { 
        d = D[j]; 
        u = j; 
       } 
      } 
      nu = 0; 
     } 
    } 
    else 
    { 
     for (int i=myId; i<=n; i += p-1) 
     { 
      D[i] = INFINITY; 
      S[i] = 0; 
     } 

     D[u] = 0; 

     ++init; 
     while (init < p-1) 
     { 
     } 
     while (u != 0) 
     { 
      C[myId] = 0; 
      int d = INFINITY; 

      for (int i = myId; i<=n; i+=p-1) 
      { 
       if (S[i] == 0) 
       { 
        if (i != u) 
        { 
         int cost = graph->getCostBetween(u, i); 
         if (cost != INFINITY) 
         { 
          D[i] = min(D[i], D[u] + cost); 
         } 
        } 
        if ((d > D[i])) 
        {       
         d = D[i]; 
         C[myId] = i; 
        } 
       } 
      } 
      ++nu; 
      while (nu != 0) 
      { 
      } 
     } 
    }  
} 

}

+2

這聽起來像是一種糟糕的方式來並行化固有的順序算法。你爲什麼這樣做?將頂點傳遞給線程的成本應該近似等於更新成本的成本。 – akappa

+0

我必須準備並行版本,以顯示當我們使用更多內核時,Dijkstra可以更快。我知道Dijkstra很難並行化,通常加速比低於1.但是我發現了一些信息,說明用加速1,2-1,4來實現這個算法。我的代碼以這種方式呈現,所以此時我想檢測到錯誤。 – mchrobok

+1

實現的「加速」取決於所使用的並行處理器的數量,所以我不明白這些數字意味着什麼。可能的話,加速取決於圖形的「密集度」以及您花費多少時間來穿過頂點。它是一種非常細粒度的方法,所以你需要一個奇妙的調整實現來實現一個明顯更快的版本(如果速度更快的話)w.r.t.順序執行。至於你的實現,我不明白你的主線程調度頂點放寬到其他線程的位置。 – akappa

回答

8

我不知道你有什麼樣的信息,但parallelising不規則,高度同步與小任務的算法是衆多棘手的並行問題你也可以擁有。研究團隊可以致力於完成這些任務,並獲得有限的加速或無處可用。通常,這些算法僅適用於爲並行化量身定製的特定體系結構,並且通過適當地設計數據結構消除了虛假共享等虛擬開銷。

像這樣的算法需要花費大量的時間和精力進行剖析,測量和考慮。例如見本文。

ww2.cs.fsu.edu/~flin/ppq_report.pdf

現在,到你的直接問題,因爲你的算法是高度同步與任務都很小,你所遇到的數據競爭的副作用。從並行算法中刪除這些內容會非常棘手,而且這裏沒有人可以爲你做。

因此,您的第一要點是查看可幫助您檢測數據競爭的工具,如Valgrind和Intel線程檢查器。