C++ OpenMP'中的数据属性;的任务

C++ OpenMP'中的数据属性;的任务,c++,task,openmp,C++,Task,Openmp,我编写了一个与OpenMP快速排序相关的代码,如下所示: #包括 #包括 #包括 #包括 #包括 使用名称空间std; #包括 无效并行快速排序(int*开始,int*结束) { 如果(开始+1

我编写了一个与OpenMP快速排序相关的代码,如下所示:

#包括
#包括
#包括
#包括
#包括
使用名称空间std;
#包括
无效并行快速排序(int*开始,int*结束)
{
如果(开始+1<结束)
{
--结束;
int*middle=partition(开始,结束,bind2nd(less(),*end));
互换(*结束,*中间);
#pragma omp任务共享(开始)firstprivate(中间)
并行快速排序(开始,中间);
#pragma omp任务共享(结束)firstprivate(中间)
并行快速排序(++middle,+++end);
}
}
int main()
{
整数n=200000000;
int*a=新的int[n];

对于(int i=0;i首先,在给定区域中被确定为
private
的变量在显式任务中会自动
firstprivate
,因此您不需要将它们显式声明为
firstprivate
。其次,您的代码包含
+-end;
--end;
,它们修改
end
的值,如果
end
shared
firstprivate
是此处正确的数据共享类,则会影响其他任务-每个任务仅保留创建任务时它们使用的
begin
end
middle
的值

您的
ParallelQuickSort
应该如此简单:

void并行快速排序(int*begin,int*end)
{
如果(开始+1<结束)
{
--结束;
int*middle=partition(开始,结束,bind2nd(less(),*end));
互换(*结束,*中间);
#pragma-omp任务
并行快速排序(开始,中间);
#pragma-omp任务
并行快速排序(++middle,+++end);
}
}
请注意,尽管此代码可以工作,但它比单线程版本慢得多:88.2秒,大型Xeon X7350(Tigerton)上有两个线程框而不是单线程50.1秒。原因是任务创建一直延续到交换两个数组元素的非常简单的任务。使用任务的开销是巨大的,您应该设置一个合理的上限阈值,在该阈值之下应该禁用任务,比如说当子数组大小达到1024个元素时。确切的数目取决于nds在OpenMP运行时实现上,您的CPU类型和内存速度,因此1024的值或多或少是随机选择的。但最佳值不应创建两个任务来处理落在同一缓存线中的元素,因此元素的数量应为16的倍数(每个缓存线64字节/4个整数字节):

void并行快速排序(int*begin,int*end)
{
如果(开始+1<结束)
{
--结束;
int*middle=partition(开始,结束,bind2nd(less(),*end));
互换(*结束,*中间);
#pragma omp任务如果((结束-开始)>1024)
并行快速排序(开始,中间);
#pragma omp任务如果((结束-开始)>1024)
并行快速排序(++middle,+++end);
}
}
通过此修改,代码在同一个框上运行两个线程,运行34.2秒