【发布时间】:2020-03-12 17:21:05
【问题描述】:
我正在修改 OpenMP 并尝试实现快速排序的并行版本。
我已经实现了一个始终将第一个元素作为枢轴的版本,它的并行化版本,通过选择三个随机元素的中值来随机化枢轴的版本,以及它的并行化版本。
令我困扰的是,我在第一次并行化时得到了很好的加速,而第二次(尽管以相同的方式并行化)比顺序并行慢。
在这两种情况下,我只并行化函数的第一次调用,我知道我可以在三个递归中更深入地并行化,但重点是我希望从两个并行化中获得相同的加速。
这是“朴素”(非随机化)分区函数的代码 sn-p:
int partition(vector<int>& v, int p, int q){
int x = v[p];
int i = p;
for(int j = p+1; j <= q; j++){
if(v[j] <= x){
i++;
swap(v[i], v[j]);
}
}
swap(v[i], v[p]);
return i;
}
这是随机分区函数:
int rand_median(const vector<int>& v, int p, int q){
int n1 = (rand() % (p - q)) + p;
int n2 = (rand() % (p - q)) + p;
int n3 = (rand() % (p - q)) + p;
if((v[n1] <= v[n2] && v[n1] >= v[n3]) || (v[n1] <= v[n3] && v[n1] >= v[n2])) return n1;
else if ((v[n2] <= v[n1] && v[n2] >= v[n3]) || (v[n2] <= v[n3] && v[n2] >= v[n1])) return n2;
else return n3;
}
int rand_partition(vector<int>& v, int p, int q){
int pivot = rand_median(v,p,q);
swap(v[p], v[pivot]);
int x = v[p];
int i = p;
for(int j = p+1; j <= q; j++){
if(v[j] <= x){
i++;
swap(v[i], v[j]);
}
}
swap(v[i], v[p]);
return i;
}
天真的快速排序:
void quicksort(vector<int>& v, int s, int e){
if(s >= e) return;
int p = partition(v,s,e);
quicksort(v,s,p-1);
quicksort(v,p+1,e);
}
并行化朴素快速排序:
void quick_par(vector<int>& v, int s, int e){
if(s >= e) return;
int p = partition(v,s,e);
omp_set_num_threads(2);
#pragma omp parallel sections
{
#pragma omp section
quicksort(v,s,p-1);
#pragma omp section
quicksort(v,p+1,e);
}
}
随机快速排序:
void quick_rand(vector<int>& v, int s, int e){
if(s >= e) return;
int p = rand_partition(v,s,e);
quick_rand(v,s,p-1);
quick_rand(v,p+1,e);
}
并行随机快速排序:
void quick_par_rand(vector<int>& v, int s, int e){
if(s >= e) return;
int p = rand_partition(v,s,e);
omp_set_num_threads(2);
#pragma omp parallel sections
{
#pragma omp section
quick_rand(v,s,p-1);
#pragma omp section
quick_rand(v,p+1,e);
}
}
以下是使用 Google 基准测试获得的结果:
bench_ser 887282457 ns 887038659 ns 10 //naive quicksort
bench_par 10738723 ns 10734826 ns 70 //parallelized naive
bench_rand 613904 ns 613686 ns 1039 //randomized quicksort
bench_par_rand 3249751 ns 3248460 ns 213 //parallelized randomized
bench_sort 106110 ns 106074 ns 5952 //std::sort
如您所见,并行随机版本比顺序版本慢。 Here 是我用过的整个代码的 pastebin。
【问题讨论】:
标签: c++ parallel-processing openmp