基于C++11 CPU多线程的 奇偶排序(没有CUDA)

来源:互联网 发布:淘宝主播super米娜华少 编辑:程序博客网 时间:2024/06/05 15:23

写的不一定对!错了求指正!

前言

这篇是用C++11 的 thread 做的。
编译大概是

g++ sort.cpp -O3 -pthread -std=c++14 -o sort

其实还没学c++14

最近开始学CUDA,感觉线程具体怎么用和硬件是直接相关的, 不同架构啊不同精度啊使用线程的方式都应该不同。这篇博客就是个实验,用CPU实现一下奇偶排序为日后与CUDA做比较

一直是CPU和GPU一起学的。二者都支持多线程,但是并不是一种线程。CPU线程更适合粗粒度的任务,而GPU线程更适合细粒度的任务。而且CUDA最小调度单位是线程束(warp).

CPU线程的创建,销毁,切换,还是比较花时间的。也就是奇偶排序不太适合CPU多线程的原因.N厂GPU每个线程都有自己的寄存器,这就很厉害了,完全就没有上下文切换的开销,就只要轻轻拨一下开关。CUDA编程一个思路就是用海量线程去掩盖访存延迟。

奇偶排序

奇偶排序思路不太难,本来就是为了并行而设计的算法。拆问题的时候就是把数据用奇偶隔开,开差不多数组长度一半数量的线程去和相邻比较。假设能够任意线程数地并行的话,那么只需要:偶比较一次,奇比较一次,偶。。。。直到完全有序 设一个flag来表示是否完成排序。

图片来自wiki,奇偶排序的过程
这里写图片描述

学习了算法课的精神,特地与vanilla quick sort,bubble sort 做比较并计时(其实没必要,奇偶排序实在太慢= =)

测试结果

LEN = 10000
vanilla quick sort 0.002025s
odd even sort 857.425s

LEN = 1000

vanilla quick sort 0.000101s
odd even sort 8.55487s

LEN = 100
vanilla quick sort 5e-06s
bubble sort 2.5e-05s
odd even sort 0.072577s

主要代码

bool Sorted = false;template<typename T=int>void sortswap(T* data,int index,int right){    if(index == right)        return;    if(data[index]>data[index+1])    {        swap(data[index],data[index+1]);        Sorted = false;    }}template<typename T=int>void oddEvenSort(T* data,int left = 0,int right = LEN-1){    int latch = (right-left)/2 + (right-left)%2;    thread threads[latch];    int start = left;    while(!Sorted)    {        Sorted = true;        for(int i = start,j = 0;j<latch;i+=2,j++)            threads[j] = thread(sortswap<T>,data,i,right);        for(int i = 0;i<latch;i++)            threads[i].join();        if(start == left)            start = left +1;        else            start = left;    }}

全部代码

#include<thread>#include<atomic>#include<ctime>#include<iostream>#include<ctime>#include<cstdlib>using namespace std;using TYPE = int;const int LEN = 100;TYPE* data = new TYPE[LEN];template<typename T=int>void disp(T* data,int l){//  cout<<__func__<<": ";    for(int i = 0;i<l;i++)    {        if((i!=0) && (i%10==0))            cout<<endl;        cout<<data[i]<<" ";    }    cout<<endl;}template<typename T=int>void init(T* data,int len){    srand(unsigned(time(0)));    for(int i = 0;i<len;i++)        data[i] = (T)rand();}template<typename T=int>void bubbleSort(T* data,int left = 0,int right = LEN-1){    for(int i = left; i < right; i++)          for (int j = i + 1; j < right; j++)              if (data[i] > data[j])                  swap(data[i], data[j]);  }template<typename T=int>void qsort(T* data,int left = 0,int right = LEN-1){    if(left < right)    {        int l = left;        int h = right;        T pivot = data[left];        while(l<h)        {            while(data[h] >= pivot && l < h) h--;            data[l] = data[h];            while(data[l]<pivot && l < h) l++;            data[h] = data[l];        }        data[l] = pivot;        qsort(data,left,l-1);        qsort(data,l+1,right);    }}bool Sorted = false;template<typename T=int>void sortswap(T* data,int index,int right){    if(index == right)        return;    if(data[index]>data[index+1])    {        swap(data[index],data[index+1]);        Sorted = false;    }}template<typename T=int>void oddEvenSort(T* data,int left = 0,int right = LEN-1){    int latch = (right-left)/2 + (right-left)%2;    thread threads[latch];    int start = left;    while(!Sorted)    {        Sorted = true;        for(int i = start,j = 0;j<latch;i+=2,j++)            threads[j] = thread(sortswap<T>,data,i,right);        for(int i = 0;i<latch;i++)            threads[i].join();        if(start == left)            start = left +1;        else            start = left;    }}template<typename T>void (*f[])(T*,int,int) = {    qsort,    bubbleSort,    oddEvenSort};int main(){    for(int i = 0;i<3;i++)    {        init<TYPE>(data,LEN);        auto t1 = clock();        f<TYPE>[i](data,0,LEN-1);        cout<<(double)(clock()-t1)/CLOCKS_PER_SEC<<endl;    }    return 0;}
0 0
原创粉丝点击