并行计算学习新手小白,第一次写并行程序,在借鉴其它代码的基础上根据自己的思路,利用OpenMP实现快速排序。
借鉴链接:https://blog.csdn.net/qq_45769678/article/details/118711856
大致思路:
先实现串行的快速排序,在串行的基础上,对递归的部分实现并行。
递归实现的每一次对更小的数据量进行的快速排序,使用task分配到不同线程并行执行,即上一次排序后返回的位置将数据分成左右两部分,两部分分别交给不同线程执行。
代码如下:
#include <iostream>
#include <omp.h>
#include <time.h>
#define n 10000
#define thread_num 100
using namespace std;
void omp_quickSort_inner1(int* B,int left,int right);
int omp_quickSort_inner2(int* B,int left,int right);
int quickSort_iner(int *A,int left,int right)
{
int i=left,j=right;
int stand=A[left];
while(i<j)
{
while(A[j]>stand&&i<j)
j--;
A[i]=A[j];
while(A[i]<stand&&i<j)
i++;
A[j]=A[i];
}
A[i]=stand;
return i;
}
void quickSort(int *A,int left,int right)
{
if(left<right)
{
int stand= quickSort_iner(A,left,right);
quickSort(A,left,stand-1);
quickSort(A,stand+1,right);
}
else
return ;
}
void omp_quickSort(int *B,int left,int right)
{
#pragma omp parallel num_threads(thread_num)//创建可分配线程数
{
#pragma omp single//串行执行
{
omp_quickSort_inner1(B,left,right);
}
}
}
void omp_quickSort_inner1(int* B,int left,int right)
{
if(left<right)
{
int stand= omp_quickSort_inner2(B,left,right);
//时间思路与串行相同,递归的两部分交给不同线程去执行
#pragma omp task//左右两侧划分为小的区间后再次快排采用并行--将两侧任务用task分配给不同线程
{
omp_quickSort_inner1(B,left,stand-1);
}
#pragma omp task
{
omp_quickSort_inner1(B,stand+1,right);
}
}
else
return ;
}
int omp_quickSort_inner2(int* B,int left,int right)
{
int i=left,j=right;
int stand=B[left];
while(i<j)
{
while(B[j]>stand&&i<j)
j--;
B[i]=B[j];
while(B[i]<stand&&i<j)
i++;
B[j]=B[i];
}
B[i]=stand;
return i;
}
int main()
{
double omp_str,omp_end;
clock_t str,end;
int *A,*B;
A=new int[n];
B=new int[n];
srand(time(0));
for(int i=0;i<n;i++)
{
A[i]=rand();
}
srand(time(0));
for(int i=0;i<n;i++)
{
B[i]=rand();
}
//串行快速排序
str=clock();
quickSort(A,0,n-1);
end=clock();
//并行快速排序
omp_str=omp_get_wtime();
omp_quickSort(B,0,n-1);
omp_end=omp_get_wtime();
cout<<"quickSort:"<<(end-str)*1.0/1000<<endl;
// for(int i=0;i<n;i++)
// cout<<A[i]<<" ";
cout<<endl;
cout<<"omp_quickSort:"<<omp_end-omp_str<<endl;
// for(int i=0;i<n;i++)
// cout<<B[i]<<" ";
cout<<endl;
}
运行结果:
quickSort:1.514
omp_quickSort:0.051453
并行部分的计时需要使用omp_get_wtime()函数,返回时间以s为单位。
clock()函数对并行程序的计时是CPU时钟计时单元数,也就是多个核心总共执行的时钟嘀嗒数。当程序单线程或者单核心机器运行时,这种时间的统计方法才是正确的。(clock()函数返回值以ms为单位)。