通过MPI并行化递归函数?

时间:2013-12-07 22:14:01

标签: recursion mpi

我们可以使用MPI并行化递归函数吗? 我试图并行化快速排序功能,但不知道它是否在MPI中工作,因为它是递归的。我也想知道我应该在哪里做并行区域。

// quickSort.c
#include <stdio.h>

void quickSort( int[], int, int);
int partition( int[], int, int);


void main() 
{
    int a[] = { 7, 12, 1, -2, 0, 15, 4, 11, 9};

    int i;
    printf("\n\nUnsorted array is:  ");
    for(i = 0; i < 9; ++i)
        printf(" %d ", a[i]);

    quickSort( a, 0, 8);

    printf("\n\nSorted array is:  ");
    for(i = 0; i < 9; ++i)
        printf(" %d ", a[i]);

}



void quickSort( int a[], int l, int r)
{
   int j;

   if( l < r ) 
   {
    // divide and conquer
        j = partition( a, l, r);
       quickSort( a, l, j-1);
       quickSort( a, j+1, r);
   }

}



int partition( int a[], int l, int r) {
   int pivot, i, j, t;
   pivot = a[l];
   i = l; j = r+1;

   while( 1)
   {
    do ++i; while( a[i] <= pivot && i <= r );
    do --j; while( a[j] > pivot );
    if( i >= j ) break;
    t = a[i]; a[i] = a[j]; a[j] = t;
   }
   t = a[l]; a[l] = a[j]; a[j] = t;
   return j;
}

如果还有另一个更简单的快速排序代码,我也会非常感激。

2 个答案:

答案 0 :(得分:0)

嗯,技术上你可以,但我担心这只会在SMP中有效。阵列是否适合单个节点?如果不是,那么即使是第一次快速排序也无法执行。

如果您真的需要使用MPI对并行系统上的数组进行排序,您可能需要考虑使用合并排序(当然,在开始合并块之前,您仍然可以对每个节点的单个块使用快速排序)

如果你仍然想使用快速排序,但是你对递归版本感到困惑,这里有一个非递归算法草图,希望可以更容易并行化,虽然它基本上是相同的:

std::stack<std::pair<int, int> > unsorted;
unsorted.push(std::make_pair(0, size-1));
while (!unsorted.empty()) {
  std::pair<int, int> u = unsorted.top();
  unsorted.pop();
  m = partition(A, u.first, u.second);

  // here you can send one of intervals to another node instead of
  // pushing it into the stack, so it would be processed in parallel. 
  if (m+1 < u.second) unsorted.push(std::make_pair(m+1, u.second));
  if (u.first < m-1) unsorted.push(std::make_pair(u.first, m-1));
}

答案 1 :(得分:0)

理论上“任何东西”都可以使用MPI并行化,但请记住MPI本身并没有进行任何并行化。它只是提供进程之间的通信层。只要您的所有发送和接收(或集体呼叫)匹配,它就是大多数情况下的正确程序。话虽如此,根据您的算法,使用MPI可能不是最有效的方法。如果你要对很多很多数据进行排序(超过一个节点的内存可以容纳),那么使用MPI(你可能想看看那个案例中的RMA章节)或者一些其他更高级别的库可能会使这类应用程序更简单(UPC,Co-array Fortran,SHMEM等)。