繁体   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