您的位置:首页 > 编程语言 > C语言/C++

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

2017-01-14 21:51 429 查看
写的不一定对!错了求指正!

前言

这篇是用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线程 cpu c++11