0

我实现了一个并行的快速排序算法。为了避免过多并行线程的开销,我有一个截止策略,当向量大小小于特定阈值时,将并行算法转换为顺序算法。但是,现在我正在尝试根据递归深度设置截止策略。即我希望我的算法在达到某个递归深度时变为顺序。我使用了以下代码,但它不起作用。我不确定如何进行。有任何想法吗?

template <class T>
void ParallelSort::sortHelper(typename vector<T>::iterator start, typename vector<T>::iterator end, int level =0) //THIS IS THE QUICKSoRT INTERFACE
{
  static int depth =0;

  const int insertThreshold = 20;
  const int threshold = 1000;
  if(start<end)
  {
    if(end-start < insertThreshold) //thresholf for insert sort
    {
      insertSort<T>(start, end);
    }
    else if((end-start) >= insertThreshold && depth<threshold) //threshhold for non parallel quicksort
    {
      int part = partition<T>(start,end);
      depth++;
      sortHelper<T>(start, start + (part - 1), level+1);
      depth--;
      depth++;
      sortHelper<T>(start + (part + 1), end, level+1);
      depth--;
    }
    else
    {
      int part = partition<T>(start,end);
      #pragma omp task
      {
        depth++;
        sortHelper<T>(start, start + (part - 1), level+1);
        depth--;
      }
      depth++;
      sortHelper<T>(start + (part + 1), end, level+1);
      depth--;
    }
  }
}

我尝试了静态变量depth和非静态变量level,但它们都不起作用。注意:以上截图仅取决于depth. level包括在内以显示两种尝试的方法

4

2 回答 2

0

static depth从两个线程写入会使您的代码执行未指定的行为,因为未指定这些写入的作用。

碰巧的是,您正在传递 down level,这是您的递归深度。在每个级别,您将线程数加倍——因此级别等于 6(比如说)的限制最多对应于 2^6 个线程。您的代码只有一半并行,因为partition代码发生在主线程中,所以您可能会少于理论上同时运行的最大线程数。

template <class T>
void ParallelSort::sortHelper(typename vector<T>::iterator start, typename vector<T>::iterator end, int level =0) //THIS IS THE QUICKSoRT INTERFACE
{

  const int insertThreshold = 20;
  const int treeDepth = 6; // at most 2^6 = 64 tasks
  if(start<end)
  {
    if(end-start < insertThreshold) //thresholf for insert sort
    {
      insertSort<T>(start, end);
    }
    else if(level>=treeDepth) // only 2^treeDepth threads, after which we run in sequence
    {
      int part = partition<T>(start,end);
      sortHelper<T>(start, start + (part - 1), level+1);
      sortHelper<T>(start + (part + 1), end, level+1);
    }
    else // launch two tasks, creating an exponential number of threads:
    {
      int part = partition<T>(start,end);
      #pragma omp task
      {
        sortHelper<T>(start, start + (part - 1), level+1);
      }
      sortHelper<T>(start + (part + 1), end, level+1);
    }
  }
}
于 2013-03-25T20:27:11.503 回答
0

好吧,我想通了。这是我的一个愚蠢的错误。

当堆栈大小大于某个阈值时,算法应该回退到顺序代码,而不是更小。这样做可以解决问题,并加快速度。

于 2013-03-25T19:46:31.663 回答