您的位置:首页 > 其它

用Parallel_For进行并行快速排序

2009-06-03 14:29 225 查看

用Parallel_For进行并行快速排序

作者: Zhouweiming 周伟明 (32 篇文章) 日期: 五月 31, 2009 在 10:43 上午

用Parallel_For进行并行快速排序

注:本文主要内容摘自笔者所著的《多核计算与程序设计》一书,略有修改,后续还会继续发布系列文章,如有需要,可以考虑将一下地址加入到您的浏览器收藏夹中:http://software.intel.com/zh-cn/blogs/category/multicore/
上一篇文章 用动态任务调度器实现Parallel_For 中,实现了Parallel_For()功能, Parallel_For()可以实现许多的并行区间处理功能,下面以并行快速排序为例来讲解如何使用Parallel_For()的功能。
要用Parallel_For()来进行并行快速排序,需要先继承CRange类来实现一个CQuickSortRange类,然后就可以将CQuickSortRange类的实例作为参数传给Parallel_For()进行并行快速排序。
CQuickSortRange类的定义如下:
template <class T>
class CQuickSortRange : public CRange {
private:
T * m_pData;
int m_nBegin;
int m_nEnd;
public:
CQuickSortRange(T *pDataArray, int nBegin, int nEnd);
virtual CRange * Split();
};

在CQuickSortRange类中,主要需要实现Split()功能。考虑到效率,当区间小于一定值时就用串行的快速排序来对区间进行排序,否则将区间拆分成两个更小的区间。
Split()的代码实现如下:
#define MIN_QUICKSORT_SIZE 512

template <class T>
CRange * CQuickSortRange<T>::Split()
{
if ( m_nEnd - m_nBegin <= MIN_QUICKSORT_SIZE )
{
QuickSort(m_pData, m_nBegin, m_nEnd);
return NULL;
}

int nMid = QuickSort_Split(m_pData, m_nBegin, m_nEnd);

CQuickSortRange<T> *pRange = new CQuickSortRange<T>(m_pData, nMid+1, m_nEnd);

m_nEnd = nMid - 1;

return pRange;
}

在Split()功能中,调用了QuickSort()函数和QuickSort_Split()函数,这两个函数的代码如下:
template <class T>
int QuickSort_Split(T *pData, int nBegin, int nEnd)
{
T SelData;
int nLow;
int nHigh;

nLow = nBegin;
nHigh = nEnd;

SelData = pData[nLow];
while ( nLow < nHigh )
{
while ( (pData[nHigh] > SelData) && (nLow != nHigh) )
{
--nHigh;
}
if ( nHigh != nLow )
{
pData[nLow] = pData[nHigh];
++nLow;
}

while ( ( pData[nLow] < SelData ) && (nLow != nHigh) )
{
++nLow;
}
if ( nLow != nHigh )
{
pData[nHigh] = pData[nLow];
--nHigh;
}
}
pData[nLow] = SelData;

return nLow;
}

template <class T>
void QuickSort(T *pData, int nBegin, int nEnd)
{
int nMid = QuickSort_Split(pData, nBegin, nEnd);
if ( nMid > nBegin )
{
QuickSort(pData, nBegin, nMid - 1);
}

if ( nEnd > nMid )
{
QuickSort(pData, nMid + 1, nEnd);
}
}

下面代码演示了如何使用Parallel_For()和CQuickSortRange类来进行快速排序。
#define QUICKSORT_DATA_SIZE 1000000

void main(void)
{
int * pData = new int[QUICKSORT_DATA_SIZE];

srand(time(NULL));

int i;
for (i = 0; i < QUICKSORT_DATA_SIZE; i++ )
{
pData[i] = rand();
}
CQuickSortRange<int> *pRange
= new CQuickSortRange<int>(pData, 0, QUICKSORT_DATA_SIZE-1);
Parallel_For(pRange);

delete [] pData;
}
相关的多核文章:

在一个双核2.66G CPU机器上,测试了100万个随机数的串行快速排序和并行快速排序,得到的性能情况大致如下(由于存在随机性,每次测试得到的时间可能有差距):

串行快速排序100万个随机数, 耗时 187ms
并行快速排序100万个随机数, 耗时 94ms

加速比为187 / 94 = 1.989
效率为:1.989 / 2 = 99.46%

从上面的性能数据可以充分看出,使用动态任务调度进行并行算法的效率之高是非常令人兴奋的。

相关多核文章:

1、原子操作在多核编程中的使用
2、OpenMP编程指南
3、并行顺序搜索及终止检测
4、用原子操作解决多线程退出问题
5、多核编程伪共享问题及其对策
6、多核编程锁竞争问题及其对策
7、程序员的十层楼 11层(上帝)
8、多核分布式队列的实现:“偷”与“自私”的运用
9、多核编程中的条件同步模式
10、多核编程的四层境界
11、“老子”是伟大的多核计算科学家
12、多核查找-顺序查找也疯狂
13、多核编程文章汇总
14、多核中的动态任务调度
15、用动态任务调度器实现Parallel_For
参考文献:
【1】 周伟明,多核分布式队列的实现:“偷”与“自私”的运用(1)

【2】 周伟明,《多核计算与程序设计》 ,华中科技大学出版社,2009.03.
【3】 Capi开源项目,链接:http://gforge.osdn.net.cn/projects/capi
【4】 Intel Thread Building Block(TBB)源代码, 链接:http://www.threadingbuildingblocks.org/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: