我用 OpenMP 编写了与快速排序相关的代码,如下所示:
#include <iostream>
#include <ctime>
#include <algorithm>
#include <functional>
#include <cmath>
using namespace std;
#include <omp.h>
void ParallelQuickSort(int *begin, int *end)
{
if (begin+1 < end)
{
--end;
int *middle = partition(begin, end, bind2nd(less<int>(), *end));
swap(*end, *middle);
#pragma omp task shared(begin) firstprivate(middle)
ParallelQuickSort(begin, middle);
#pragma omp task shared(end) firstprivate(middle)
ParallelQuickSort(++middle, ++end);
}
}
int main()
{
int n = 200000000;
int* a = new int[n];
for (int i=0; i<n; ++i)
{
a[i] = i;
}
random_shuffle(a, a+n);
cout<<"Sorting "<<n<<" integers."<<endl;
double startTime = omp_get_wtime();
#pragma omp parallel
{
#pragma omp single
ParallelQuickSort(a, a+n);
}
cout<<omp_get_wtime() - startTime<<" seconds."<<endl;
for (int i=0; i<n; ++i)
{
if (a[i] != i)
{
cout<<"Sort failed at location i="<<i<<endl;
}
}
delete[] a;
return 0;
}
我在代码中遇到的问题是函数内任务构造中的数据属性ParallelQuickSort
。变量 middle 应该firstprivate
代替,shared
因为它可能会被执行这两个任务的线程更改。但是,如果我按照代码所示设置变量 begin 和 end shared
,程序将失败。我想知道为什么他们 ( begin
and end
) 应该firstprivate
代替shared
. 在我看来,由于执行这两个任务的线程分别保持变量begin
和end
,它们不会相互影响。另一方面,ParallelQuickSort
函数是递归的,因此变量begin
或end
(例如,在父函数和子函数中)。我不确定这个嫌疑人,因为变量在不同的函数(父函数和子函数)中。