簡體   English   中英

Dijkstra算法OpenMP比單線程慢

[英]Dijkstra Algorithm OpenMP Slower than Single Thread

我正在嘗試使用OpenMP並行化Dijkstra的算法,但串行版本的運行速度快了40倍。 我可能缺少一個概念或做錯了什么。 我是並行和OpenMP的新手。 你能幫忙嗎? 謝謝。

long* prev; // array of pointers to preceding vertices
long* dist; // array of distances from the source to each vertex
long* visited; // visited vertices, 0 if not visited, 1 otherwise
long** vSetDistance; // distance between i and j

void dijkstraAlgorithm(
      long * prev, 
      long * dist, 
      long * visited, 
      long ** vSetDistance) 
   {
   int i, j, min;

   // Initialization: set every distance to INFINITY until we discover a path
   for (i = 1; i <= numVertices; i++) 
      {
      prev[i] = -1;
      visited[i] = 0;
      dist[i] = INFINITY;
      }

   // The distance from the source to the source is defined to be zero
   dist[sourceVertex] = 0; 

      {
      for (j = 1; j <= numVertices; j++)
         {
         min = -1;

#pragma omp parallel default(none) private(i, j) \
   shared(min, visited, dist, prev, vSetDistance, numVertices)

            {
            /* This loop corresponds to sending out the explorers walking the paths,
             * where the step of picking "the vertex, v, with the shortest path to s"
             * corresponds to an explorer arriving at an unexplored vertex */

#pragma omp for

            for (i = 1; i <= numVertices; i++)
#pragma omp critical
               {
               if (!visited[i] && ((min == -1) || (dist[i] <= dist[min])))
                  min = i;
               }

            visited[min] = 1; // visited = true

            // relaxation
#pragma omp for
            for (i = 1; i <= numVertices; i++) 
               {
               if (vSetDistance[min][i]) 
                  {
                  if ((dist[min] + vSetDistance[min][i]) < dist[i]) 
                     {
                     dist[i] = dist[min] + vSetDistance[min][i];
                     prev[i] = min;
                     }
                  }
               }
            }
         }
      }
   }

並行化並非總是免費獲得更高性能的門票。 我看到可能導致減速的兩件事。

  1. 關鍵部分可能花費大量時間來處理同步。 我並不完全了解這些部分在OpenMP中的實現方式,但我的第一個猜測是它們使用互斥鎖來鎖定對該部分的訪問。 互斥鎖並不是很便宜,鎖定/解鎖比您要執行的操作要昂貴得多。 另外,由於循環完全在關鍵部分中,因此除了一個線程外,所有線程都將只等待關鍵部分中的線程完成。 本質上,該循環仍將以串行方式完成,同時增加了同步開銷。

  2. 可能沒有足夠的頂點可以從並行化中受益。 同樣,啟動線程不是免費的,並且開銷可能比獲得的時間大得多。 隨着頂點數量變小,這一點變得越來越明顯。

我的猜測是,第一個問題是大多數減速發生的地方。 減輕此問題的最簡單方法是簡單地以串行方式進行。 其次,您可以嘗試讓每個線程僅在自己的部分中找到最小值,然后在並行部分之后將它們串行比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM