OpenMP实现快速排序

 并行计算学习新手小白,第一次写并行程序,在借鉴其它代码的基础上根据自己的思路,利用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为单位)。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值