ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:147.50KB ,
资源ID:12273705      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12273705.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(并行归并排序.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

并行归并排序.docx

1、并行归并排序串行归并与并行归并排序算法串行归并排序算法归并排序是一种很容易进行并行化的算法,因为归并的各个数据区间都是独 立的,没有依赖关系。并且归并排序是一种速度比较快的排序, 且是一种稳定的 排序算法,排序速度与关键词初始排列无关。串行归并排序的算法大体的可以描述为:首先将要排序的表分成两个节点个 数基本相等的子表,然后对每个子表进行排序,最后将排好序的两个子表合并成 一个子表。在对子表进行排序时可以将子表再分解成两个节点数量基本相同的子 表,当子表足够小时,也可以采用其他排序方法对子表进行排序, 然后再对排好序的子表进行归并操作,最后将整个表排好序。1、 1算法流程图并行归并排序算法的流

2、程图:串行归并排序算发流程图1、 2 代码分析#include using namespace std;#define N 11int arrayN = 4, 67, 456, 23, 1, 78, 26, 222, 34, 432, 12 ; 待/ 排序数组 int otherN; / 辅助空间 ,用以暂存已经排序的数组元素void Swap(int &a, int &b)int tmp = a;a = b;b = tmp;/* array 待排序数组* begin 数组开始的下标* end 数组最后一个元素的下标*/void MergeSort(int *array, int begin,

3、 int end) if(end-begin+1 2)MergeSort(array, begin, (end+begin)/2); MergeSort(array, (end+begin)/2+1, end);int i = begin, j = (end+begin)/2+1, k=begin; while(i=(begin+end)/2 & j=end) if(arrayi arrayj) otherk+ = arrayi+;elseotherk+ = arrayj+;while(i = (begin+end)/2)otherk+ = arrayi+;while(j = end) oth

4、erk+ = arrayj+; for(k=begin; k=end; +k) arrayk = otherk; elseif(arrayend arraybegin) Swap(arrayend, arraybegin); void Output(i nt *array, int n)for(i nt i=0; in; +i)coutarrayi;coute ndl;int main()cout串行归并排序算法endlthe numbers are:;Output(array, N);MergeSort(array, 0, N-1);cout i;return 0;1、3运行结果I c :

5、s and Se ft i DLKsVAdBini str at orVBjr DomentsWisnuaJLthe numbers are 4 6? 456 23 1 78 26 222 34 432 12 the sorted resultil 4 12 23 26 34 6? 78 223 432 4S61、4复杂度分析通过算法分析很容易发现串行归并排序算法的时间复杂度地推公式为: (1)丿 if(n =1)T( n)= n2T(3)+o(n)if (n 1)这是一个时间复杂度的递推公式,我们需要消去等号右侧的 T(n),把T(n)写成n的函数。其实符合一定条件的 Recurrenee的

6、展开有数学公式可以套,这 里我们略去严格的数学证明,只是从直观上看一下这个递推公式的结果。当n=1 时可以设T(1) = g,当n1时可以设T(n)=2丁(厂3,我们取C1和C2中较大2的一个设为c,把原来的公式改为:T(n )=cif (n = 1) n、 ., 八2匕)cnif(n J参照主定理公式T (n) = aT f (n),可以知道当n1时,有以下b等式成立:a 2b = 2f (n)二 cn同时又有下面的等式成立:f (n)= cn= & (nlogb )则有T(n)满足主定理公式的第二种情况,也即是 T(n)的时间复杂度为:T(n)= (nlo“ lg n)= (nlgn)并行

7、归并排序算法由串行归并排序算法可知,归并的各个数据区间都是独立的,没有依赖关系。 因此归并排序是一种很容易进行并行化的算法。其方案是先将待排序区间划分成 若干个相等的小区间,然后并行地对这些小区间进行排序,最后再通过归并的方 法将所有排好序的小区间归并成一个有序系列。由于归并时是一层层向上进行的,因此需要将区间划分成 2k个小区间,这 样第1轮归并时,可以将2k个小区间归并成2kJ个区间。这样过k轮归并操作后就 归并成一个有序的大区间。这也正是并行归并排序的算法思想。2、1算法流程图并行归并排序算法的思想可以通过下面的流程图表示:开始并行归并排序算发流程图2、2代码分析功能函数头文件:Merg

8、eSort.h#define MAX_MERGE_TURN 24#define MIN_PARALLEL_SORT_COUNT 3#define MIN_MERGE_COUNT 2#define CACHE_LINE_SIZE 64 typedef unsigned int UINT;#include #include #include #include #include using namespacestd;int compare( int * one, int * two) if (*one *two)return 1;else if (*two *one)return -1;else r

9、eturn 0;void *GetCacheAlignedAddr( void *pAddr)int m = CACHE_LINE_SIZE;void *pRet = ( void *)(UINT)pAddr+m-1)&(-m);return pRet; /* 串行归并函数归并好的数据存放在输出参数ppNewDat中param void *ppData - 待归并的数据param int nStart1 -param int nEnd1 -第个区间的开始位置 ( 包括 nStart1)第个区间的结束位置 ( 包括 nEnd1)param int nStart2 - 第个区间的开始位置(包括nS

10、tart2)param int nEnd2 - 第个区间的结束位置(包括nEnd2)param COMPAREFUNC func 比- 较函数param void *ppNewData - 存放归并后的数据return void* - 返回归并后的数据指针(等于ppNewData)*/int * Serial_Merge( int *ppData, int nStart1, int nEnd1, int nStart2, int nEnd2, int (*func)( int *, int *) , int *ppNewData)int i, j, k;i = nStart1; j = nSt

11、art2; k = nStart1;for ( i = nStart1; i = nEnd1;)for ( ; j = nEnd2; j+ )if ( (*func)(ppDatai, ppDataj) nEnd2 )for ( ; i nEnd1 )for ( ; j = nEnd2; j+ )ppNewDatak = ppDataj; +k;for (i = nStart1; i = nEnd2; i+) ppDatai = ppNewDatai;return ppData;/* 串行归并排序函数param void *ppData - 待排序数据 param int nBegin - 排

12、序区间的开始位置param int nEnd - 排序区间的结束位置param COMPAREFUNC func 数- 据大小比较函数return void - 无*/void Serial_MergeSort( int *ppData, int nBegin, int nEnd, int (*func)( int *, int *)if ( nEnd - nBegin *ppDatanEnd)temp = ppDatanBegin; ppDatanBegin = ppDatanEnd; ppDatanEnd = temp;return ;int * tempData = new int *n

13、End - nBegin + 1; int i;int tmpInt = 0;for (i = 0; i 1; / 除以Serial_MergeSort(ppData, nBegin, nMid, func);Serial_MergeSort(ppData, nMid+1, nEnd, func);Serial_Merge(ppData, nBegin, nMid, nMid+1, nEnd, func, tempData); /* 并行归并快速排序函数param void *ppData - 待排序数据param int nLen - 待排序数据长度param COMPAREFUNC fun

14、c 数- 据比较回调函数 return void - 无*/void Parallel_MergeSort( int *ppData, int nLen, int (*func)( int *, int *)int i, k;int nStep;int nLoopCount;int nCore; int nStart1, nEnd1;if ( nLen MIN_PARALLEL_SORT_COUNT )Serial_MergeSort(ppData, 0, nLen - 1, func ); return ;nCore = omp_get_num_procs();int nCount = nL

15、en / MIN_PARALLEL_SORT_COUNT;int nTurn = MAX_MERGE_TURN;nLoopCount = 1 nCount )nLoopCount = nLoopCount 1; / 除以-nTurn;/判断nTurn是否为奇数if ( (nLoopCount nCore) & (nTurn 0x1) &(nTurn & 0x1) = 0x1) )-nTurn; /把nTurn变成偶数,便于后面不拷贝数据 nLoopCount = nLoopCount 1;nStep = nLen / nLoopCount;int *p = new int nLoopCount

16、*2 + CACHE_LINE_SIZE; int *pnPos = ( int *)GetCacheAlignedAddr(p);/将数据分成nLoopCount个小区间,并行地对每个区间进行串行排序#pragma omp parallel for private (nStart1, nEnd1) num_threads(nCore)for ( i = 0; i nLoopCount; i+)nStart1 = i * nStep;nEnd1 = nStart1 + nStep - 1;if ( i = nLoopCount - 1 ) nEnd1 = nLen - 1;Serial_Mer

17、geSort(ppData, nStart1, nEnd1, func); pnPosi + i = nStart1;pnPosi + i + 1 = nEnd1;/ 对排好序的各个相邻区间进行并行归并操作int *pp = new int *nLen + CACHE_LINE_SIZE;int * ppOutData = ( int *)GetCacheAlignedAddr( int *)pp);int * ppMergeData = ppData;int * ppTempOutData = ppOutData;int * ppSwap;nStep = 2;for ( k = 0; k n

18、Turn; k+ )#pragma omp parallel for num_threads(nCore)for ( i = 0; i 1; / 除以nStep += nStep;ppSwap = ppMergeData;ppMergeData = ppTempOutData;ppTempOutData = ppSwap;/将数据写回到ppData中,如果nTurn为偶数则下面的判断内的循环不会被执行if ( ppMergeData = ppOutData )#pragma omp parallel for num_threads(nCore) for ( i = 0; i nLen; i+

19、)ppDatai = ppOutDatai;delete p; delete pp;return ;测试文件: Test.cpp#include MergeSort.h /test MergeSortvoid testFunc( int size)Sleep(IOOO); /防止srand取同样的值int i; int cost;SYSTEMTIME lpsystimeStr;SYSTEMTIME lpsystimeEnd;new int *size;new int *size; new int size;new int size;int * ppDataForSerial = int * p

20、pDataForParallel = int * tempArrForSerial = int * tempArrForParallel =srand( unsigned int )time(O);for (i = O; i size; i+)tempArrForSeriali = rand(); tempArrForParalleli = tempArrForSeriali; ppDataForSeriali = tempArrForSerial + i; ppDataForParalleli = tempArrForParallel + i;cout 测试 size 个数字串行归并算法:

21、endl;GetLocalTime(&lpsystimeStr);printf(开始时间:年月日星期 %u %u:%u:%u:%un:lpsystimeStr.wYear,lpsystimeStr.wMo nth,lpsystimeS tr.wDay,lpsystimeStr.wDayOfWeek,lpsystimeStr.wHour,lpsystimeStr.wMinu te,lpsystimeStr.wSecond,lpsystimeStr.wMilliseconds);Serial_MergeSort(ppDataForSerial, 0, size - 1, compare);GetL

22、ocalTime(&lpsystimeEnd);printf(结束时间:%1年%i月日星期 %u %u:%u:%u:%un:lpsystimeE nd.wYear,lpsystimeE nd.wM on th,lpsystimeE nd.wDay,lpsystimeEnd.wDayOfWeek,lpsystimeEnd.wHour,lpsystimeEnd.wMinu te,lpsystimeEnd.wSecond,lpsystimeEnd.wMilliseconds);cost = lpsystimeEnd.wMilliseconds - lpsystimeStr.wMilliseconds

23、;if (cost = 0)cost = cost + (lpsystimeEnd.wSecond - lpsystimeStr.wSecond) *1000;cout 共耗时: cost ms。 endl;cout 串行归并排序后前个数字: ;for (i = 0; i 10; i+)if (0 = i % 6)cout endl;cout *ppDataForSeriali ;cout endl;cout endl;cout 测试 size 个数字并行归并算法: endl;GetLocalTime(&lpsystimeStr);printf(开始时间:%U年%i月日星期 %u %u:%u:

24、%u:%un:lpsystimeStr.wYear,lpsystimeStr.wMo nth,lpsystimeS tr.wDay,lpsystimeStr.wDayOfWeek,lpsystimeStr.wHour,lpsystimeStr.wMinu te,lpsystimeStr.wSecond,lpsystimeStr.wMilliseconds);Parallel_MergeSort(ppDataForParallel, size, compare);GetLocalTime(&lpsystimeEnd);printf(结束时间:%1年%月 %日星期 %u %u:%u:%u:%un:

25、lpsystimeE nd.wYear,lpsystimeE nd.wM on th,lpsystimeE nd.wDay,lpsystimeEnd.wDayOfWeek,lpsystimeEnd.wHour,lpsystimeEnd.wMinu te,lpsystimeEnd.wSecond,lpsystimeEnd.wMilliseconds);cost = lpsystimeEnd.wMilliseconds - lpsystimeStr.wMilliseconds;if (cost = 0)cost = cost + (lpsystimeEnd.wSecond - lpsystimeS

26、tr.wSecond) *1000; endl;II IIcout 共耗时: cost ms。cout 并行归并排序后前个数字: for (i = 0; i 10; i+)if (0 = i % 6)cout endl;cout *ppDataForParalleli cout endl;cout endl;delete tempArrForSerial; delete tempArrForParallel;delete ppDataForSerial; delete ppDataForParallel;int main()testFunc(500); testFunc(10000); tes

27、tFunc(50000); testFunc(100000); testFunc(500000); testFunc(800000); testFunc(1000000); return 0;2、3运行结果90耶 10991 1VS&G 19951 27G47 31583?14 11H7 15351 15563 17871 2488925730 26176 30056 36583洌试10fl呼个数窃任归并算20123 g!7B片间:泗12年3月即日(7V耗日7h lt0ns o舁轩归并排序石前个数字测试50个数宇幷jf归并尊注 旺始时 汕曄年m月汐日J 结朿日寸间,2“2年3月貂日J 共耗时Gna 坪忏归井排序石前加个数字:7710

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1