简体   繁体   English

Dijkstra算法OpenMP比单线程慢

[英]Dijkstra Algorithm OpenMP Slower than Single Thread

I'm trying to parallelise Dijkstra's Algorithm using OpenMP but the serial version runs x40 times faster. 我正在尝试使用OpenMP并行化Dijkstra的算法,但串行版本的运行速度快了40倍。 I might be missing a concept or doing something wrong. 我可能缺少一个概念或做错了什么。 I'm new to parallelism and OpenMP. 我是并行和OpenMP的新手。 Can you please help out? 你能帮忙吗? Thanks. 谢谢。

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

Parallelization isn't always a free ticket to higher performance. 并行化并非总是免费获得更高性能的门票。 I see two things that could be causing the slowdown. 我看到可能导致减速的两件事。

  1. The critical section is probably spending a lot of time dealing with synchronization. 关键部分可能花费大量时间来处理同步。 I'm not entirely familiar with how those sections are implemented in OpenMP but my first guess would be that they use mutexes to lock access to that section. 我并不完全了解这些部分在OpenMP中的实现方式,但我的第一个猜测是它们使用互斥锁来锁定对该部分的访问。 Mutexes aren't super cheap to lock/unlock, and that operation is much more expensive than the operations you want to perform. 互斥锁并不是很便宜,锁定/解锁比您要执行的操作要昂贵得多。 In addition, since the loop is entirely in a critical section, all but one of the threads will just be waiting around for the thread in the critical section to finish. 另外,由于循环完全在关键部分中,因此除了一个线程外,所有线程都将只等待关键部分中的线程完成。 Essentially, that loop will still be done in a serial fashion with the added overhead of synchronization. 本质上,该循环仍将以串行方式完成,同时增加了同步开销。

  2. There may not be enough vertices to benefit from parallelization. 可能没有足够的顶点可以从并行化中受益。 Again, starting threads isn't free, and the overhead may be significantly larger than the time gained. 同样,启动线程不是免费的,并且开销可能比获得的时间大得多。 This becomes more and more pronounced as the number of vertices becomes smaller. 随着顶点数量变小,这一点变得越来越明显。

My guess is that the first problem is where most of the slowdown occurs. 我的猜测是,第一个问题是大多数减速发生的地方。 The easiest way to mitigate this problem is to simply do it in a serial fashion. 减轻此问题的最简单方法是简单地以串行方式进行。 Second, you could try having each thread find the minimum only in its own section, and them compare those in serial after the parallel portion. 其次,您可以尝试让每个线程仅在自己的部分中找到最小值,然后在并行部分之后将它们串行比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM