用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/
相关文章推荐
- C# 并行循环Parallel.For
- Parallel ForEach For 多线程并行计算使用注意
- Oracle 11g 使用 dbms_parallel_execute 对大表进行并行update
- 用Parallel.For()和Parallel.For<TLocal>()方法实现并行运行迭代
- opencv 并行计算函数 parallel_for_的使用
- [C#]『Parallel.For』『Parallel.ForEach』任务并行库使用小计
- Oracle 11g 使用 dbms_parallel_execute 对大表进行并行update
- 并行运算(Parallel)(For、Foreach)_VS2010&.Net 4.0
- C# 使用Parallel并行开发Parallel.For、Parallel.Foreach实例
- C#并行运算 Parallel.Invoke、Parallel.For、Parallel.Foreach性能测试及示例
- 【并行计算】基于OpenMP的并行编程(#pragma omp parallel for)
- 对纯for循环进行并行流和线程池优化简记
- VS2010&.Net 4.0 之并行运算(Parallel)(For、Foreach)
- c# Parallel.For 并行编程 执行顺序测试
- 并行计算—parallel,for联合使用
- C# 使用Parallel并行开发Parallel.For、Parallel.Foreach实例
- 用Parallel.For()和Parallel.For<TLocal>()方法实现并行运行迭代
- .Net 4.0 之并行运算(Parallel)(For、Foreach)
- C# 使用Parallel并行开发Parallel.For、Parallel.Foreach实例
- 用Parallel.For()和Parallel.For<TLocal>()方法实现并行运行迭代