mpi并行编程程序单机多线程可以运行,为什么多机计算时出现错

帐号:密码:下次自动登录{url:/nForum/slist.json?uid=guest&root=list-section}{url:/nForum/nlist.json?uid=guest&root=list-section}
贴数:7&分页:FireHawk发信人: FireHawk (FireHawk), 信区: NumComp
标&&题: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出现错
发信站: 水木社区 (Thu Jun 18 21:36:48 2015), 站内 && 最近弄了一个基于MPI的Fortran计算程序,采用非阻塞方式进行通信。在单机多线程时,没有问题,扩展性还行。但是准备进行多机并行时,出现类似如下的错误:
forrtl:severe&157& program Exception-access violation
stack trace terminated abnormally
job aborted
rank: none: exit code
0:&&&&jd1: 157: process 0 exited without calling finalize
1:&&&&jd1: 123
2:&&&&jd1: 123
3:&&&&jd1: 157: process 3 exited without calling finalize
4:&&&&jd2: 123
5:&&&&jd2: 123
6:&&&&jd2: 123
7:&&&&jd2: 123 && 经过测试发现,可能是在进行数据发送和接收时出现了错误,但是每次出现错误使程序无法运行的位置不是固定的,而且这个位置也会随着线程数发生显著变化。比如我如果用采两台机子各一个线程进行并行测试时,程序出错的位置就被推后了不少。 && 请问有经验的大牛,这个问题一般是怎么产生的呢?是程序设计问题还是与两台机子的硬件环境有关系呢?该怎么排查解决呢?万分感谢,我已经被这问题折磨一周了。
-- && ※ 来源:·水木社区 ·[FROM: 113.200.79.*]
Tony庄主发信人: Tommy003 (Tony庄主), 信区: NumComp
标&&题: Re: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出
发信站: 水木社区 (Thu Jun 18 21:53:42 2015), 站内 &&&& 我也是搞CFD模拟的,尝试了好多次几台电脑并行计算,始终没有搞成功。在这里希望你能成功,到时候分享一下经验,谢谢。 && 【 在 FireHawk 的大作中提到: 】
: 最近弄了一个基于MPI的Fortran计算程序,采用非阻塞方式进行通信。在单机多线程时,没有问题,扩展性还行。但是准备进行多机并行时,出现类似如下的错误:
: forrtl:severe&157& program Exception-access violation
: ...................
&& -- && ※ 来源:·水木社区 ·[FROM: 123.157.71.*]
建议刑法设立卢瑟罪和猥琐罪发信人: ruster (建议刑法设立卢瑟罪和猥琐罪), 信区: NumComp
标&&题: Re: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出
发信站: 水木社区 (Sat Jun 20 10:37:19 2015), 站内 && 像是send-recieve的时候某个参数的类型错了 && 【 在 FireHawk (FireHawk) 的大作中提到: 】
: 最近弄了一个基于MPI的Fortran计算程序,采用非阻塞方式进行通信。在单机多线程时,没有问题,扩展性还行。但是准备进行多机并行时,出现类似如下的错误:
: forrtl:severe&157& program Exception-access violation
: ...................
国家枪毙局执行纲要:
1.数量与质量兼顾,保证数量,尽量超额完成任务。
2.枪毙,注射和电椅,凌迟并行,发展交通肇事等新型执行手段。
3.枪毙温拿和枪毙卢瑟搭配,温拿优先。
4.子弹费五毛七分和日元均可,鼓励五毛。 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 59.44.151.*]
FireHawk发信人: FireHawk (FireHawk), 信区: NumComp
标&&题: Re: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出
发信站: 水木社区 (Sat Jun 20 10:49:45 2015), 站内 && 好的,我试试。那为啥单机多线程时没问题呢?
【 在 ruster 的大作中提到: 】
: 像是send-recieve的时候某个参数的类型错了
-- && ※ 来源:·水木社区 ·[FROM: 117.136.25.*]
建议刑法设立卢瑟罪和猥琐罪发信人: ruster (建议刑法设立卢瑟罪和猥琐罪), 信区: NumComp
标&&题: Re: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出
发信站: 水木社区 (Sat Jun 20 10:50:50 2015), 站内 && 存储空间对位不一样,另外也可能有些东西共享数据了 &&&& 【 在 FireHawk (FireHawk) 的大作中提到: 】
: 好的,我试试。那为啥单机多线程时没问题呢?
国家枪毙局执行纲要:
1.数量与质量兼顾,保证数量,尽量超额完成任务。
2.枪毙,注射和电椅,凌迟并行,发展交通肇事等新型执行手段。
3.枪毙温拿和枪毙卢瑟搭配,温拿优先。
4.子弹费五毛七分和日元均可,鼓励五毛。 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 59.44.151.*]
FireHawk发信人: FireHawk (FireHawk), 信区: NumComp
标&&题: Re: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出
发信站: 水木社区 (Sat Jun 20 10:52:23 2015), 站内 && 哦。好的,我再调试一下。谢谢师兄!
【 在 ruster 的大作中提到: 】
: 存储空间对位不一样,另外也可能有些东西共享数据了
-- && ※ 来源:·水木社区 ·[FROM: 117.136.25.*]
慢性子发信人: jman (慢性子), 信区: NumComp
标&&题: Re: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出
发信站: 水木社区 (Sun Jun 21 22:17:48 2015), 站内 && 使用什么方案? &&&& 【 在 Tommy003 (Tony庄主) 的大作中提到: 】
: 标&&题: Re: [求助]MPI并行程序单机多线程可以运行,为什么多机计算时出
: 发信站: 水木社区 (Thu Jun 18 21:53:42 2015), 站内
: 我也是搞CFD模拟的,尝试了好多次几台电脑并行计算,始终没有搞成功。在这里希望你能成功,到时候分享一下经验,谢谢。
: 【 在 FireHawk 的大作中提到: 】
: : 最近弄了一个基于MPI的Fortran计算程序,采用非阻塞方式进行通信。在单机多线程时,没有问题,扩展性还行。但是准备进行多机并行时,出现类似如下的错误:
: : forrtl:severe&157& program Exception-access violation
: : ...................
: ※ 来源:·水木社区 ·[FROM: 123.157.71.*]
&&&& -- && ※ 来源:·水木社区 newsmth.net·[FROM: 36.45.172.*]
文章数:7&分页:
抽奖到手软!将狂欢进行到底!并行计算和多线程的区别_百度知道只需一步,快速开始
扫一扫,访问微社区
查看: 1014|回复: 8
【已解决,但有新问题】Fluent 15.0多机分布式并行计算设置
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
才可以下载或查看,没有帐号?
本帖最后由 suhuihot 于
10:32 编辑
  我两台电脑,一台台式机,CPU是E3-线程,3.3GHz,Win7;另一台工作站,CPU是E5-线程,2.4GHz,Server 2008 R2
  按网上14.0的步骤安装了Intel MPI和Platform MPI;
  两台电脑都设置了共享,并且成功共享;
  都设立了相同登录用户名(Administrator)和密码;
  安装了rshd和smpd服务,wmpiregister设置了前面设置过的用户名和密码;
  Fluent安装路径都一样,在D:\program files\ansys inc下。
如图,MPI type选Intel
忽略警告,按OK、yes,运行是这样的
MPI type选PCMPI,同样忽略警告,OK、yes启动,终于说要输密码了(暗暗高兴)
可是却说密码错这可是刚刚设置的密码啊!怎么也不会记错
我这到底是肿膜了?
=================================================================华丽分割线
原来的设置不对。如图,Fluent路径必须是网络路径,即使是本机作为主机。
在任意文件夹下(应该非中文)用记事本写主机名列表的TXT文件,登录界面打开后可以点右边这个打开编辑
另外,RSHD可以不用装,SMPD安装完Intel MPI就有了,不用再安装服务。安装MPI后要运行IE浏览器最后提示的bat文件设置密码
================================================================新问题来了
2台机并行运算速度跟1台差不多
3台并行比1台还慢
每台CPU都100%了
你的节点文件打开看看就知道了。
首先多谢老大!这么忙还抽空回复
然后…小白一枚节点文件在哪?怎么看?
不好意思,又麻烦您了&
你的节点文件打开看看就知道了。
首先多谢老大!这么忙还抽空回复
然后…小白一枚节点文件在哪?怎么看?
不好意思,又麻烦您了
2台系统和硬件不同的机器可以做FLUENT分布并行计算吗?想知道结果
照说是可以的,不然分布式计算就没意义了。可是我还没搞出来,不知道哪里不对&
2台系统和硬件不同的机器可以做FLUENT分布并行计算吗?想知道结果
照说是可以的,不然分布式计算就没意义了。可是我还没搞出来,不知道哪里不对
大多数情况下,分布式并行节点都是采用完全相同的计算机,异构计算机做分布并行比较难做,期待楼主的结果。&
照说是可以的,不然分布式计算就没意义了。可是我还没搞出来,不知道哪里不对
大多数情况下,分布式并行节点都是采用完全相同的计算机,异构计算机做分布并行比较难做,期待楼主的结果。
刚试了完全一样的电脑,还是一样
大多数情况下,分布式并行节点都是采用完全相同的计算机,异构计算机做分布并行比较难做,期待楼主的结果 ...
刚试了完全一样的电脑,还是一样
本帖最后由 suhuihot 于
10:49 编辑
运算速度没有明显提升,难道是通讯问题?
明显工作站单独运行时速度最快,怎么感觉速度是最慢的那台决定的?
分到每个CPU上的计算量相同的话,可能的确是由最慢的CPU决定运算速度。你可能需要调整每个CPU的计算量,这个我也不会,看看帮助吧。&
运算速度没有明显提升,难道是通讯问题?
明显工作站单独运行时速度最快,怎么感觉速度是最慢的那台决定的 ...
分到每个CPU上的计算量相同的话,可能的确是由最慢的CPU决定运算速度。你可能需要调整每个CPU的计算量,这个我也不会,看看帮助吧。
Powered by
&nbsp &nbsp并行计算与多核多线程技术
课程报告 - 博客频道 - CSDN.NET
分类:大学生活
并行计算与多核多线程技术
专业&&&&&&&&软件工程&&&&&
&&&&&&&&&&&班级&&&&&&&&计
&&&&&&&&&&&学号&&&&&XXXXXXXXX&&&
&&&&&&&&&&&姓名&&&&&&&&&XX&&&&&&&&
&&&&2015年&月&日
课程报告要求
手写内容:设计目的、意义,设计分析,方案分析,功能模块实现,最终结果分析,设计体会等。
&&&&&允许打印内容:设计原理图等图形、图片,电路图,源程序。硬件类的设计,要有最终设计的照片图;软件类设计,要有各个功能模块实现的界面图、输入输出界面图等。
实践效果(正确度加速比)
1.&设计目的、意义(功能描述)
蒙特·卡罗方法(Monte&Carlo&method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法。本次大作业主要是对蒙特·卡罗方法进行并行处理,通过、、、、等一系列并行技术和并行机制对该算法进行并行处理,从而也进一步熟悉了蒙特·卡罗方法的串行算法和并行算法,实现了用蒙特卡罗方法计算出半径为单位的球体的体积,体会到了并行技术在实际生活中的应用。
2.&方案分析(解决方案)
蒙特·卡罗方法(Monte&Carlo&method)是指使用(或更常见的伪随机数)来解决很多计算问题的方法。球的体积可以估算为:位于点模型内随机点个数与全体随机点个数的比值乘以包围盒的体积算的。
3.&设计分析
3.1&串行算法设计
假定球体用表示,半径单位,是包含的参考立方体(在本例中是边长为的正方体),在中产生个均匀分布的伪随机点。对每个随机点检测其是否在内,假设位于内的随机点个数为()(),应用蒙特卡洛算法,则的体积为
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&V=V1(())
其中是的体积。如果产生足够多的随机点,理论上可以获得任意逼近精度。
&&&算法描述如下:
&&&&&&&BEGIN
&&&&&&&&&&&&N=_MAX;
&&&&&&&&&&&&&FOR&I=0;I&_MAX;I++
&&&&&&&&&&&&&&&X=RANDOM();
&&&&&&&&&&&&&&&Y=RANDOM();
&&&&&&&&&&&&&&&Z=RANDOM();
&&&&&&&&&&&&&&&&&&IF&(X*X+Y*Y+Z*Z)&=1
&&&&&&&&&&&&&&&&&&&&&COUNT++;
&&&&&&&&&&&&&&&&&&&END&IF;
&&&&&&&&&&&&&&END&FOR;
&&&&&&&&&&&BULK=V1*()
&&&&&&&END;
&&&&本算法主要是在参考立方体的选取上和定义的的值对结果影响较大,所以应该选择合适的数。
3.2&并行算法设计
对循环进行划分使用两个处理器完成计算。例如对一个长为的序列,首先划分得到两个长为的序列,将其交给两个处理器分别处理;而后进一步划分得到四个长为的序列,再分别交给四个处理器处理;如此递归下去最终得到结果。当然这是理想的划分情况,如果划分步骤不能达到平均分配的目的,那么结果的效率会相对较差。
&&&伪代码如下:
&&&&&BEGIN
&&&&&&&&&&&&N=_MAX;
&&&&&&&&&&&&&FOR1&&I=0;I&_MAX/2;I++
&&&&&&&&&&&&&&&X1=RANDOM();
&&&&&&&&&&&&&&&Y1=RANDOM();
&&&&&&&&&&&&&&&Z1=RANDOM();
&&&&&&&&&&&&&&&&&&IF&(X1*X1+Y1*Y1+Z1*Z1)&=1
&&&&&&&&&&&&&&&&&&&&&COUNT1++;
&&&&&&&&&&&&&&&&&&&END&IF;
&&&&&&&&&&&&&&END&FOR1;
&&&&&&&&&&&&&FOR2&I=_MAX/2+1;I&_MAX;I++
&&&&&&&&&&&&&&&X2=RANDOM();
&&&&&&&&&&&&&&&Y2=RANDOM();
&&&&&&&&&&&&&&&Z2=RANDOM();
&&&&&&&&&&&&&&&&&&IF&(X2*X2+Y2*Y2+Z2*Z2)&=1
&&&&&&&&&&&&&&&&&&&&&COUNT2++;
&&&&&&&&&&&&&&&&&&&END&IF;
&&&&&&&&&&&&&&END&FOR2;
&&&&&&&&&&&BULK=V1*(())
&&&&&&&END;
3.3&理论加速比分析
实验中大量数据所产生的加速比比小量数据所产生的加速比要体现得更明显,并且数据生成的并行加速比随着处理器核的增加而增加。设处理器个数为,数据量为,由于正常情况下该快速排序算法的复杂度为并行处理的时间复杂度为其中所以并行算法的时间复杂度为理论加速比为
4.&功能模块实现与最终结果分析
4.1&基于的并行算法实现
4.1.1&主要功能模块与实现方法
利用了里面的将对两个循环用两个线程并行化执行,以多线程方式并行运行程序,并行的算法步骤如下:
&&&()初始化_max&=&;
&&&()创建两个线程;
&&&()由编译指导语句控制产生并行执行代码区段;
&&&()将数据存放到tianqing_
&&&()各线程调用算法得出结果;
并行算法的部分代码如下:
#pragma&omp&parallel&for&private(tianqing_x,tianqing_y,tianqing_z)&reduction(+:tianqing_count2)
for&(tianqing_i&=&0;&tianqing_i&tianqing_&tianqing_i++)
tianqing_x&=&rand();
tianqing_x&=&tianqing_x&/&32767;
tianqing_y&=&rand();
tianqing_y&=&tianqing_y&/&32767;
tianqing_z&=&rand();
tianqing_z&=&tianqing_z&/&32767;
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count2++;
tianqing_bulk&=&8&*&((double)(tianqing_count2)&/&tianqing_max);
4.1.2&实验加速比分析
实验中创建了两个线程,通过多次测试,得出实验结果:由上面的理论加速比分析可知,当线程数为时,理论加速比为但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值实验加速比在1.9左右,比较符合常理。
4.2&基于的并行算法实现
4.2.1&主要功能模块与实现方法
主要利用了的()函数和函数进行各个进程之间的通信,算法步骤如下:
&&&()初始化_max&=&;
&&&()动态申请2个数组,分别记录分块的起始地址、各个进程所获得的数据个数;
&&&()各个进程之间进行通信,发送接收各个进程的起始地址与数据大小;
&&&()并行执行算法;
&&&()得出结果;
伪代码如下:
//初始化执行环境
MPI_Init(&argc,&&argv);
//用获得进程的,该值为到间的整数相当于进程的
MPI_Comm_rank(MPI_COMM_WORLD,&&myid);
//用获得进程个数&
MPI_Comm_size(MPI_COMM_WORLD,&&numprocs);
MPI_Get_processor_name(processor_name,&&namelen);
&&MPI_Bcast(&tianqing_n,1,MPI_INT,0,MPI_COMM_WORLD);//将值广播出去
算法执行;
MPI_Reduce(&tianqing_bulk,&&pi,&1,&MPI_DOUBLE,&MPI_SUM,&0,&MPI_COMM_WORLD);//各个进程并行计数得到的计数总和
&&&&&&&&&&&&获得结果。
4.2.2&实验加速比分析
实验中使用了两个处理器,因此理论加速比应该为,通过多次测试,得出实验结果:加速比:,由于客观因素的影响,结果合理。
4.3&基于的并行算法实现
4.3.1&主要功能模块与实现方法
在中,创建用户自己的线程类,使用启动线程的方法启动线程对象,使之从新建状态转入就绪状态,定义线程操作的方法,并定义新的方法覆盖原来的方法。
伪代码如下
&&&&And&thread1=new&And(1,);
&&&&And&thread2=new&And(2,);
long&startTime=System.currentTimeMillis();
启动线程1和线程2;
&&&&&等待进程结束;
And&and=new&And(a,);
bulk1=8*((b*1.0)/tianqing_n);
4.3.2&实验加速比分析
实验中创建了两个线程,通过多次测试,得出实验结果:由上面的理论加速比分析可知,当线程数为时,理论加速比为但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值实验加速比在1.9左右,比较符合常理。
4.4&基于的并行算法实现
4.4.1&主要功能模块与实现方法
这里主要用到了的进入点函数,在进程中创建一个线程时,也必须给这个线程提供一个进入点函数。线程函数必须返回一个值,它将成为该线程的退出代码。使用函数创建线程,用函数管理线程来监测多个对象。采用来设置事件处理线程间的同步问题。
伪代码如下:
&&DWORD&WINAPI&ThreadOne(LPVOID&param)
对前一半数据进行处理;
SetEvent(finish[0]);
DWORD&WINAPI&ThreadTwo(LPVOID&param)
对后一半数据进行处理;
SetEvent(finish[1]);
创建两个事件;
HANDLE&thread1=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);//两个并行线程
HANDLE&thread2=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
WaitForMultipleObjects(2,finish,true,INFINITE);
得出结果;&&&&
4.4.2&实验加速比分析
实验中创建了两个线程,通过多次测试,得出实验结果:由上面的理论加速比分析可知,当线程数为时,理论加速比为但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值实验加速比在1.6左右。
4.5&基于的并行算法实现
4.5.1&主要功能模块与实现方法
先创建代理,指定要由该线程执行的线程函数,然后将代理传递给类的构造函数,调用类的方法启动新的线程然后调用方法保证应用程序域等待异步程序结束后才终止运行。
伪代码如下
&&&&Stopwatch&stopwatch&=&new&Stopwatch();
&&&&创建Work类的对象work1;
ThreadStart&thread1&=&new&ThreadStart(()&=&&work1.pSumto(b,&0,&MAXN&-&1));&&&&&&&&&&&&&&&
Thread&newthread1&=&new&Thread(thread1);
&&&&创建Work类的对象work2;
ThreadStart&thread2&=&new&ThreadStart(()&=&&work2.pSumto(c,&0,&MAXN&-&1));&
Thread&newthread2&=&new&Thread(thread2);
&&&&stopwatch.Start();
启动线程1和线程2;
&&&&等待进程结束;
&&&&stopwatch.Stop();
&&&&得到结果;
4.5.2&实验加速比分析
实验中创建了两个线程,通过多次测试,得出实验结果:由上面的理论加速比分析可知,当线程数为时,理论加速比为但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值实验加速比在6~2.7左右。
4.6&并行计算技术在实际系统中的应用
4.6.1&主要功能模块与实现方法
该飞机订票系统主要实现了对机票的一些基本信息进行存储和管理的功能。在系统中实现了对机票信息的增删改查,考虑到查询的方便性,对机票按照航班号进行排序,而此排序方法用并行快速排序运用进来。利用的并行技术,对机票信息按顺序排列好,并分析了实验过程中的加速比。
4.6.2&实验加速比分析
实验中创建了两个线程,通过多次测试,得出实验结果:当数据量比较大时,加速比理论在1.9左右。数据量较大时体现出来的加速比更准确。由上面的理论加速比分析可知,当线程数为时,理论加速比为但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值实验加速比在2~2.4左右。
5.&设计体会
虽然没有按时完成作业,但这份报告花了我好几天的时间,从开始的搭建并行计算平台到最后的程序运行成功可以说是对我的一个锻炼。每一次的遇到问题与每一次的解决问题都是一个成长。每一次遇到问题和解决问题都是一种锻炼,一种尝试,从我们上并行计算课我懂得了很多电脑硬件和软件的知识,这些可能对于我们这个专业以后都是没有机会接触的,所以我觉得选择了并行计算与多核多线程技术这门课是非常正确的。对、、、、的并行技术有了一定的了解。在搭建并行程序这块,学习的知识尤为增加,这些都是在不断的摸索、学习中学会的。
这次的大作业虽然是对以前实验的整合,但它加深了我对并行计算的印象,也使我对并行计算知识的理解更加深刻,也使我认识到了自己很多不足之处。学习并行计算的历程不会因为完成本次大作业而停止,我们是为了用知识武装大脑而学习,通过学习充实自己的生活,要努力学习,争取以后能够完成规模更大的程序。
6.1&基于的并行程序设计
6.1.1&代码及注释
#include&&omp.h&
#include&&Windows.h&
#include&iostream&
#include&stdlib.h&
#include&time.h&
using&namespace&
long&int&tianqing_max&=&;
long&int&tianqing_i,&tianqing_count1&=&0,tianqing_count2&=&0;
double&tianqing_x,&tianqing_y,&tianqing_z,&tianqing_bulk,&tianqing_start_time,&tianqing_end_
void&Mframe();
void&C_Bulk()
tianqing_start_time&=&clock();
time_t&tianqing_t;
srand((unsigned)time(&tianqing_t));//函数产生一个以当前时间开始的随机种子
for&(tianqing_i&=&0;&tianqing_i&tianqing_&tianqing_i++)
tianqing_x&=&rand();
//生成之间的一个随机数,其中是中定义的一个整数,它与系统有关。&
/*是中中宏定义的一个字符常量:& 
   其值最小为最大为
&通常在产生随机小数时可以使用。
tianqing_x&=&tianqing_x&/&32767;
tianqing_y&=&rand();
tianqing_y&=&tianqing_y&/&32767;
tianqing_z&=&rand();
tianqing_z&=&tianqing_z&/&32767;
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count1++;
tianqing_bulk&=&8&*&(double(tianqing_count1)&/&tianqing_max);
tianqing_end_time&=&clock();
cout&&&&&球体的体积为
cout&&&&&串行运算时间为
//(2)并行执行程序:利用&语句和归并语句对程序进行并行化。
void&B_Bulk()
tianqing_start_time&=&clock();
time_t&tianqing_t;
srand((unsigned)time(&tianqing_t));//函数产生一个以当前时间开始的随机种子
#pragma&omp&parallel&for&private(tianqing_x,tianqing_y,tianqing_z)&reduction(+:tianqing_count2)
//reduction子句为变量指定一个操作符,每个线程都会创建变量的私有拷贝,在区域结束处,将使用各个线程的私有拷贝的值通过制定的操作符进行迭代运算,并赋值给原来的变量。
for&(tianqing_i&=&0;&tianqing_i&tianqing_&tianqing_i++)
tianqing_x&=&rand();
tianqing_x&=&tianqing_x&/&32767;
tianqing_y&=&rand();
tianqing_y&=&tianqing_y&/&32767;
tianqing_z&=&rand();
tianqing_z&=&tianqing_z&/&32767;
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count2++;
tianqing_bulk&=&8&*&((double)(tianqing_count2)&/&tianqing_max);
tianqing_end_time&=&clock();
cout&&&&&球体的体积为
cout&&&&&并行运算时间为
int&main()
6.1.2&执行结果截图
加速比为:&1.833。
6.1.3&遇到的问题及解决方案
&&&&在运行的并行程序,计算的球体的体积是串行计算的结果的倍。
&&&&由于在定义变量后,串行和并行用的都是同一个变量,执行完串行程序后变量没有清零,导致了并行的结果是串行的倍。
解决方法:
&&&分别定义了变量和。
6.2&基于的并行程序设计
6.1.1&代码及注释
#include&&mpi.h&
#include&&stdlib.h&
#include&&stdio.h&
#include&&conio.h&
#include&&iostream&
#pragma&comment&(lib,&&mpi.lib&)&
int&main(int&argc,&char*&argv[])
long&int&tianqing_n=&;
long&int&tianqing_i,&tianqing_count&=&0,tianqing_done=0;
double&tianqing_x,&tianqing_y,&tianqing_z,&tianqing_bulk,&tianqing_start_time,&tianqing_end_
int&myid,&
double&mypi,
char&processor_name[MPI_MAX_PROCESSOR_NAME];
//初始化执行环境
MPI_Init(&argc,&&argv);
//用获得进程的,该值为到间的整数相当于进程的
MPI_Comm_rank(MPI_COMM_WORLD,&&myid);
//用获得进程个数&
MPI_Comm_size(MPI_COMM_WORLD,&&numprocs);
MPI_Get_processor_name(processor_name,&&namelen);
printf(&Process&%d&of&%d&on&%s\n&,&myid,&numprocs,&processor_name);
fflush(stdout);
tianqing_start_time&=&MPI_Wtime();
&&MPI_Bcast(&tianqing_n,1,MPI_INT,0,MPI_COMM_WORLD);//将值广播出去
for&(tianqing_i&=&myid+1;&tianqing_i&&&tianqing_n;&tianqing_i+=numprocs)
tianqing_x&=&rand();
//生成之间的一个随机数,其中是中定义的一个整数,它与系统有关。
/*是中中宏定义的一个字符常量: 
   其值最小为最大为  
&通常在产生随机小数时可以使用。
tianqing_x&=&tianqing_x&/&32767;
tianqing_y&=&rand();
tianqing_y&=&tianqing_y&/&32767;
tianqing_z&=&rand();
tianqing_z&=&tianqing_z&/&32767;
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count++;
&&&&&&&&&&&}
//mypi=tianqing_
tianqing_bulk&=&8&*&(double(tianqing_count)&/&tianqing_n);
//mypi=tianqing_
MPI_Reduce(&tianqing_bulk,&&pi,&1,&MPI_DOUBLE,&MPI_SUM,&0,&MPI_COMM_WORLD);//各个进程并行计数得到的计数总和
if(myid==0)
&&&tianqing_end_time&=&MPI_Wtime();
&&&printf(&球体的体积
&&&&printf(&运算时间
MPI_Finalize();
6.2.2&执行结果截图
串行执行结果:
并行执行结果:
加速比:1.282
6.2.3&遇到的问题及解决方案
&&&&在运行程序后,没有输出结果。
&&&&对的一些函数不理解。
解决方法:
&&&通过看书和询问别人,程序运行成功。
6.3&基于的并行程序设计
6.3.1&代码及注释
package&java1;
import&java.util.R
public&class&java1&extends&Thread{
private&long&tianqing_start,tianqing_
public&static&long&tianqing_n=;
long&tianqing_count1&=&0;
public&java1(long&tianqing_start,long&tianqing_end){//构造函数
this.tianqing_start=tianqing_
this.tianqing_end=tianqing_
public&void&run(){
double&tianqing_x,&tianqing_y,&tianqing_z;
Random&random&=&new&Random();
for&(&long&tianqing_i&=&tianqing_&tianqing_i&&&tianqing_&tianqing_i+=2)
tianqing_x&=&random.nextDouble();
tianqing_y&=&random.nextDouble();
tianqing_z&=&random.nextDouble();
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count1++;
public&long&serial(){&&&&&&&&&&&&&&//串行执行函数
double&tianqing_x,&tianqing_y,&tianqing_z;
long&tianqing_count2&=&0;
Random&random&=&new&Random();
for&(&long&tianqing_i&=&tianqing_&tianqing_i&&&tianqing_&tianqing_i++)
tianqing_x&=&random.nextDouble();
tianqing_y&=&random.nextDouble();
tianqing_z&=&random.nextDouble();
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count2++;
return&tianqing_count2;
public&long&getsum(){&&&&&&&&&&&&
return&tianqing_count1;
public&static&void&main(String[]&args)throws&InterruptedException{
double&bulk1,bulk2;
java1&thread1=new&java1(1,);&//创建线程
java1&thread2=new&java1(2,);
long&startTime=System.currentTimeMillis();
thread1.start();&&&&&&&&&&&&&&&&&&&&&&&&&//直接调用方法进入执行状态
thread2.start();
System.out.println(&并行结果
thread1.join();&&&&&&&&&&&&&&&&&&&&&&&&&&//避免执行结果出错异常错误
thread2.join();
b=thread1.getsum()+thread2.getsum();
bulk1=8*((b*1.0)/tianqing_n);
&&&&&&&&System.out.println(&\n球的体积为
&&&&&&&&long&endTime=System.currentTimeMillis();
&&&&&&&&System.out.println(&并行时间
&&&&&&&&//串行执行
&&&&&&&&startTime=System.currentTimeMillis();&&&&//调用系统的进行计时
&&&&&&&&System.out.println(&串行结果
&&&&&&&&java1&serial=new&java1(1,);
&&&&&&&&c=serial.serial();
&&&&&&&&bulk2&=&8&*&((c*1.0)&/&tianqing_n);
System.out.println(&\n球的体积为
endTime=System.currentTimeMillis();
System.out.println(&串行&时间
6.3.2&执行结果截图
加速比:1.438
6.3.3&遇到的问题及解决方案
如图所示:求得体积都为零。
&&&&对中产生随机数的函数不是很了解,不清楚函数产生的随机数在何种范围之内。
解决方法:
&&&通过网上查询和询问别人,程序运行成功。
6.4&基于的并行程序设计
6.4.1&代码及注释
#include&stdio.h&
#include&&time.h&
#include&&omp.h&
#include&&Windows.h&
HANDLE&finish[2];
static&long&tianqing_n&=&;
double&tianqing_sum[2]&=&{0.0,0.0};
double&&tianqing_bulk1,&tianqing_bulk2,&tianqing_start_time,&tianqing_end_
DWORD&WINAPI&ThreadOne(LPVOID&param){&//&&&&线程函数&
double&tianqing_x,&tianqing_y,&tianqing_z,&tianqing_count1&=&0;
for&(&int&tianqing_i&=&0;&tianqing_i&&&(tianqing_n/2);&tianqing_i++)
tianqing_x&=&rand();
//生成之间的一个随机数,其中是中定义的一个整数,它与系统有关。
/*是中中宏定义的一个字符常量: 
   其值最小为最大为  
&通常在产生随机小数时可以使用。
tianqing_x&=&tianqing_x&/&32767;
tianqing_y&=&rand();
tianqing_y&=&tianqing_y&/&32767;
tianqing_z&=&rand();
tianqing_z&=&tianqing_z&/&32767;
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count1++;
tianqing_sum[0]&=&tianqing_count1;
SetEvent(finish[0]);&&&&&&&&&//设置事件状态为激发状态
DWORD&WINAPI&ThreadTwo(LPVOID&param){
double&tianqing_x,&tianqing_y,&tianqing_z,&tianqing_count2&=&0;
for&(int&tianqing_i&=&(tianqing_n&/&2)&+&1;&tianqing_i&&&tianqing_n;&tianqing_i++)
tianqing_x&=&rand();
//生成之间的一个随机数,其中是中定义的一个整数,它与系统有关。
/*是中中宏定义的一个字符常量: 
   其值最小为最大为  
&通常在产生随机小数时可以使用。
tianqing_x&=&tianqing_x&/&32767;
tianqing_y&=&rand();
tianqing_y&=&tianqing_y&/&32767;
tianqing_z&=&rand();
tianqing_z&=&tianqing_z&/&32767;
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count2++;
tianqing_sum[1]&=&tianqing_count2;
SetEvent(finish[1]);
int&main(int&argc,&char*&argv[])
double&sumparallel&=&0;
//并行执行
clock_t&start&=&clock();&&&&&&&&&&&&&&&&&&&&&&&&&&//开始计时
finish[0]&=&CreateEvent(NULL,&false,&false,&NULL);&&&//创建激发线程的事件
finish[1]&=&CreateEvent(NULL,&false,&false,&NULL);
HANDLE&thread1&=&CreateThread(NULL,&0,&ThreadOne,&NULL,&0,&NULL);//创建线程,并且创建之后就会被立即执行
//Sleep(20000);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//线程等待&&&&&&&
HANDLE&thread2&=&CreateThread(NULL,&0,&ThreadTwo,&NULL,&0,&NULL);
WaitForMultipleObjects(2,&finish,&true,&INFINITE);&//用来检测多个对象,并且保证两个线程的工作能全部完成
for&(int&i&=&0;&i&&&2;i++)
sumparallel+=tianqing_sum[i];
tianqing_bulk1&=&8&*&(sumparallel/&(tianqing_n*1.0));
clock_t&end&=&clock();&&&&&&&&&&&&&&&&&&&&&&&&&&&&//结束计时
//串行执行
double&sumserial&=&0;
double&tianqing_x,&tianqing_y,&tianqing_z,&tianqing_count3&=&0;;
clock_t&start2&=&clock();
for&(int&tianqing_i&=&0;&tianqing_i&&&tianqing_n;&tianqing_i++)
tianqing_x&=&rand();
tianqing_x&=&tianqing_x&/&32767;
tianqing_y&=&rand();
tianqing_y&=&tianqing_y&/&32767;
tianqing_z&=&rand();
tianqing_z&=&tianqing_z&/&32767;
if&((tianqing_x*tianqing_x&+&tianqing_y*tianqing_y&+&tianqing_z*tianqing_z)&&=&1)
tianqing_count3++;
sumserial&=&tianqing_count3;
tianqing_bulk2&=&8&*&((double)(sumserial)&/&tianqing_n);
clock_t&end2&=&clock();
printf(&\n并行结果
printf(&并行计时
printf(&串行计数
printf(&串行计时
6.4.2&执行结果截图
加速比:1.014
6.4.3&遇到的问题及解决方案
&&&遇到的问题与中的问题一样,都是求得球的体积为零。
&&&&由于程序中不同类型的变量太多,导致在变量之间相互赋值时出现了类型之间转换错误,导致了结果等于。
解决方法:
&&&通过网上查询和求助别人,程序运行成功。
6.5&基于的并行程序设计
6.5.1&代码及注释
using&System.Collections.G
using&System.L
using&System.T
using&System.T
using&System.D
namespace&Net1
&&&&class&Threads
&&&&&&&&static&void&Main(string[]&args)
&&&&&&&&&&&&long&tianqing_n&=&;
&&&&&&&&&&&&double&tianqing_bulk1,&tianqing_bulk2,&sumserial,&a;
&&&&&&&&&&&&Stopwatch&stopwatch&=&new&Stopwatch();&&&&&&//用来测量运行时间的类
&&&&&&&&&&&&Work&work1&=&new&Work(1);
&&&&&&&&&&&&ThreadStart&thread1&=&new&ThreadStart(work1.pSumto);
&&&&&&&&&&&&Thread&newthread1&=&new&Thread(thread1);
&&&&&&&&&&&&Work&work2&=&new&Work(2);
&&&&&&&&&&&&ThreadStart&thread2&=&new&ThreadStart(work2.pSumto);
&&&&&&&&&&&&Thread&newthread2&=&new&Thread(thread2);
&&&&&&&&&&&&stopwatch.Start();&&&&&//开始测量用于并行执行的时间
&&&&&&&&&&&&newthread1.Start();&&&&//进程1调用start方法,处于就绪状态
&&&&&&&&&&&&newthread2.Start();
&&&&&&&&&&&&newthread1.Join();&&&&&//防止异步程序非正常终止
&&&&&&&&&&&&newthread2.Join();
&&&&&&&&&&&&stopwatch.Stop();
&&&&&&&&&&&&TimeSpan&timespan&=&stopwatch.E&//记录一个时间间隔
&&&&&&&&&&&&sumserial&=&work1.getSum()&+&work2.getSum();
&&&&&&&&&&&&tianqing_bulk1&=&8&*&((sumserial)&/&tianqing_n);
&&&&&&&&&&&&double&millseconds&=&timespan.TotalM//将时间间隔用毫秒的形式表现出来
&&&&&&&&&&&&Console.WriteLine(&\nparallel&sum={0}&,&tianqing_bulk1);
&&&&&&&&&&&&Console.Write(&parallel&time=&);
&&&&&&&&&&&&Console.WriteLine(millseconds);
&&&&&&&&&&&&stopwatch.Start();&&&&&//开始测量用于串行执行的时间
&&&&&&&&&&&&a=new&Work(1).sumto();
&&&&&&&&&&&&tianqing_bulk2=8&*&((a)&/&tianqing_n);
&&&&&&&&&&&&Console.WriteLine(&\nserial&sum={0}&,&tianqing_bulk2);
&&&&&&&&&&&&stopwatch.Stop();
&&&&&&&&&&&&TimeSpan&timespan2&=&stopwatch.E
&&&&&&&&&&&&double&millseconds2&=&timespan2.TotalM
&&&&&&&&&&&&Console.Write(&serial&time=&);
&&&&&&&&&&&&Console.WriteLine(millseconds2);
&&&&class&Work
&&&&&&&&public&long&
&&&&&&&&public&long&tianqing_n&=&;
&&&&&&&&double&tianqing_sum&=&0;
&&&&&&&&public&Work(long&i)
&&&&&&&&&&&&this.start&=&i;
&&&&&&&&public&void&pSumto()&&&//并行执行过程
&&&&&&&&&&&double&tianqing_x,&tianqing_y,&tianqing_z;
&&&&&&&&&&&&Random&ran&=&new&Random();
&&&&&&&&&&&&for&(long&tianqing_i&=&&tianqing_i&&&tianqing_n;&tianqing_i&+=&2)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&tianqing_x&=&ran.NextDouble();
&&&&&&&&&&&&&&&&tianqing_y&=&ran.NextDouble();
&&&&&&&&&&&&&&&&tianqing_z&=&ran.NextDouble();
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&if&((tianqing_x&*&tianqing_x&+&tianqing_y&*&tianqing_y&+&tianqing_z&*&tianqing_z)&&=&1)
&&&&&&&&&&&&&&&&&&&&tianqing_sum++;
&&&&&&&&&&&&}
&&&&&&&&public&double&sumto()&&//串行执行过程
&&&&&&&&&&&&double&tianqing_x,&tianqing_y,&tianqing_z;
&&&&&&&&&&&&double&tianqing_count2&=&0;
&&&&&&&&&&&&Random&ran&=&new&Random();
&&&&&&&&&&&&for&(long&tianqing_i&=&&tianqing_i&&&tianqing_n;&tianqing_i&+=&1)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&tianqing_x&=&ran.NextDouble();
&&&&&&&&&&&&&&&&tianqing_y&=&ran.NextDouble();
&&&&&&&&&&&&&&&&tianqing_z&=&ran.NextDouble();
&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&if&((tianqing_x&*&tianqing_x&+&tianqing_y&*&tianqing_y&+&tianqing_z&*&tianqing_z)&&=&1)
&&&&&&&&&&&&&&&&&&&&tianqing_count2++;
&&&&&&&&&&&&}
&&&&&&&&&&&&return&tianqing_count2;
&&&&&&&&public&double&getSum()&&//
&&&&&&&&&&&&return&tianqing_
6.5.2&执行结果截图
加速比:2.973
6.5.3&遇到的问题及解决方案
&&&算出的体积不对。
&&&&对中随机数的产生范围不了解。
解决方法:
&&&通过网上查询和求助别人,程序运行成功。
网上查询结果如下:
除了Random.Next()方法之外,Random类还提供了Random.NextDouble()方法产生一个范围在0.0-1.0之间的随机的双精度浮点数:
6.6并行计算技术在实际应用系统的应用
6.6.1&代码及注释
//飞机订票系统快速排序算法
#include&iostream&
#include&&omp.h&
#include&fstream&
#include&stdio.h&//标准输入、输出头文件
#include&string.h&//包含字符串函数处理头文件
#include&string&
#define&N&10000//定义最多的航班数
#define&M&10000//定义最大的乘客数
#include&&time.h&
using&namespace&std;
void&Mframe();//主界面
struct&air&&&&&&&&&//定义飞机结构体数组
int#//定义航班号
string&start;//航班起始站
string&over;//终点站
string&time;//航班日期
string&starttime;//航班起飞时间
string&overtime;//到达时间void&xiugai()
double&price;&&&&&&&&&&&//票价
int&zhekou;&&&&&&&&&&//折扣
int&count;//机票数量
}s[N],b[N],c[N];
struct&user&&&&&&&&&&//客户信息
string&uname;&&&&&&&//姓名
string&unumber;&&&&&//证件号
int&&ucount1;&&&&&&&&//订票数量
&&&&int&dname;&&&&&&&&//订单编号
int&dnum;&&&&&&&&&//航班号
string&dstartcity;//航班起始站
string&dovercity;//终点站
string&dtime;//航班日期
string&dstarttime;//航班起飞时间
string&dovertime;//到达时间
double&dprice;&&&&&&&&&&&//票价
int&i,&m&=&0,&m3&=&0,count_len1,&count_len2;//定义全局变量
char&ii[10];
void&add();//函数声明增加航班信息函数
void&print();&//显示航班信息
void&dingpiao();//订票业务
void&tuipiao();//退票
void&save();//保存文件
void&output();//输出格式
void&paixu();//航班排序
void&paixu1();//按航班号从小到大排序
void&paixu2();//从大到小
void&xiugai();&&&&&&//修改航班信息
void&search();//查找航班信息
void&searchNum();//定义查询函数(按航班号查询)
void&searchTime1();//定义查询函数(按起飞时间查询)
void&searchTime2();//定义查询函数(按到达时间查询)
void&searchCity1();//定义查询函数(按起飞城市查询)
void&searchCity2();//定义查询函数(按终点站查询)
void&read2();&&&&&&&&//读取message.txt
void&mymessage();&&&//我的信息
void&quickSort(air&A[]&,&int&first&,&int&end&);
clock_t&time1;
clock_t&time2;
void&jisubi();
void&merge();
#include&aiportF.h&
&int&main()
Mframe();//主界面
&void&Mframe()&&&&&&&&&&&&&&//主界面
&int&a;&&//序号
&cout&&&&&&&&&&&&&&&&&&&&&&&&&欢迎使用华夏飞机订票系统\n&;&&&&&&&&&&&&&&&&&&&&&//打印出系统主界面
&cout&&&================================================================================&&&&endl;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&1.增加航班信息\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2.浏览航班信息\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&3.查找航班信息\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&4.航班排序(按航班号)\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&5.订票业务\n&&;
&&&&&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&6.退票业务\n&;
&&&&&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&7.查看我的信息\n&;
&&&&&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&8.修改航班信息\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&9.加速比\n&;
&&&&&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&0.退出\n&;
&cout&&&================================================================================&&&&endl;
&cout&&&请在0-7中选择以回车键结束:&&;
&switch(a)
case&1:add();//增加数据
case&2:print();//调用显示模块
case&3:search();//调用查找模块
case&4:paixu();//调用排序函数
case&5:dingpiao();//调用订票模块
case&6:tuipiao();&//调用退票模块
case&7:mymessage();//查看我的信息
case&8:xiugai();&&&//修改航班信息
case&9:jisubi();
case&0://退出系统
cout&&&谢谢使用,再见!&&;
&&&cout&&&输入有误!请重新输入!&&&endl;
&&&Mframe();
void&add()//定义增加航班信息函数
ofstream&outfile1;
outfile1.open(&hangban.txt&,ios::out);
cout&&&请依次输入航班信息(以回车键结束):&&&&endl;&&&&&&//打印提示信息
&&&&cout&&&--------------------------------------------------------------------------&&&&endl;
cout&&&请输入航班号:&&;
cin&&s[i].num;//输入航班号
cout&&&请输入起始站:&&;
cin&&s[i].start;//输入起始站
cout&&&请输入终点站:&&;
cin&&s[i].over;//输入终点站
cout&&&请输入时间(星期几):&&;
cin&&s[i].time;//输入日期
cout&&&请输入起飞时间:&;
cin&&s[i].starttime;&&//输入起飞时间
cout&&&请输入到达时间:&;
cin&&s[i].overtime;&&//输入到达时间
cout&&&请输入票价:&;
cin&&s[i].price;&&&&//输入票价
cout&&&请输入票价折扣:&;
cin&&s[i].zhekou;&&&//输入票价折扣
cout&&&请输入机票数:&&;
cin&&s[i].count;//输入机票数
i++;
m++;
cout&&&添加完毕,是否继续添加?请键入y或n以回车键结束:&;
}while(!strcmp(ii,&y&));//判断是否继续添加
count_len1&=&i&/&2;
count_len2&=&i&-&count_len1;
for(int&m5=0;m5&i;m5++)&&&&&&&&//存入”hangban.txt“
&&&&&&&outfile1&&s[m5].num&&&&&&&s[m5].start&&&&&&&s[m5].over&&&&&&&s[m5].time&&&&&&&s[m5].starttime&&&&&&&s[m5].overtime&&&&&&&s[m5].price&&&&&&&s[m5].zhekou&&&&&&&s[m5].count&&endl;
for&(int&i1&=&0;&i1&&&count_len1;&i1++)
b[i]&=&s[i];
for&(int&i1&=&count_len1;&i1&&&i;&i1++)
c[i&-&count_len1]&=&s[i];
void&output()//定义输出格式函数
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&for(i=0;i&m;i++)
cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
void&print()//定义显示航班信息函数
cout&&&\n目前我们有如下航班:\n&;
output();//调用输出格式函数
&&&&cout&&&\n请按回车键返回上层菜单&&;
getchar();
getchar();
void&search()&&&//查询
cout&&&&&&&&&&&&&&&&&&&&&&&&&欢迎使用华夏飞机订票系统\n&;&&&&&&&&&&&&&&&&&&&&&//打印出系统主界面
cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&-------查询系统\n&;
&cout&&&================================================================================&&&&endl;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&1.按航班号查询\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2.按起飞时间查询\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&3.按到达时间查询\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&4.按起飞城市查询\n&;
&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&5.按终点站查询\n&&;
&&&&&cout&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&6.主菜单\n&;
&&&&&cout&&&================================================================================&&&&endl;
&cout&&&请在1-6中选择以回车键结束:&&;
switch(x1)
&&&&case&1:&searchNum();;//按航班号查询
case&2:searchTime1();//按起飞时间查询
case&3:searchTime2();//按到达时间查询
case&4:searchCity1();//按起飞城市查询
case&5:searchCity2();//按终点站查询
case&6:Mframe();//返回主界面
&&&cout&&&输入有误!请重新输入!&&&endl;
&&&search();
void&searchNum()//定义查询函数(按航班号查询)
cout&&&\n请输入航班号:&&;
cin&&n;//输入查询的航班号
for(i=0;i&m;i++)
if(s[i].num==n)//按航班号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&&&&&&&&&&&&&goto&loop;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop:cout&&&是否继续查找?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否重新查找
void&searchTime1()//定义查询函数(按起飞时间查询)
string&time1;
string&time2;
cout&&&\n请输入起飞时间:&&;
cin&&time1;//输入起飞时间
for(i=0;i&m;i++)
time2=s[i].starttime;
if(time2==time1)//按航班号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&&&&&&&&&&&&&goto&loop;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop:cout&&&是否继续查找?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否重新查找
void&searchTime2()//定义查询函数(按到达时间查询)
string&time1;
string&time2;
cout&&&\n请输入到达时间:&&;
cin&&time1;//输入到达时间
for(i=0;i&m;i++)
time2=s[i].starttime;
if(time2==time1)//按航班号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&&&&&&&&&&&&&goto&loop;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop:cout&&&是否继续查找?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否重新查找
void&searchCity1()//定义查询函数(按起飞城市查询)
string&city1;
string&city2;
cout&&&\n请输入起点站:&&;
cin&&city1;//输入起点站:
for(i=0;i&m;i++)
city2=s[i].start;
if(city2==city1)//按航班号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&&&&&&&&&&&&&goto&loop;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop:cout&&&是否继续查找?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否重新查找
void&searchCity2()//定义查询函数(按终点站查询)
string&city1;
string&city2;
cout&&&\n请输入终点站:&&;
cin&&city1;//输入终点站:
for(i=0;i&m;i++)
city2=s[i].start;
if(city2==city1)//按终点号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&&&&&&&&&&&&&goto&loop;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop:cout&&&是否继续查找?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否重新查找
void&search1()&//退订票时用的查询函数
cout&&&\n请输入航班号:&&;
cin&&n1;//输入查询的航班号
for(i=0;i&m;i++)
if(s[i].num==n1)//按航班号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&goto&loop;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop:cout&&&是否继续查找?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否继续查找
void&xiugai()
&&&int&k1,n1;
&&&&&&&if(k1==0)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&cout&&&请先添加航班信息!&&&endl;
&&&&&&&&&&&&&&&&goto&loop;
&&&&&&&&&&&&}
cout&&&\n请输入要修改的航班号:&&;
cin&&n1;//输入查询的航班号
for(i=0;i&m;i++)
&&&&&if(s[i].num==n1)//按航班号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&cout&&&请重新输入该航班的信息:&&&endl;
&&&&cout&&&请输入起始站:&&;
&&&&&&&&cin&&s[i].start;//输入起始站
&&&&&&&&cout&&&请输入终点站:&&;
&&&&&&&&cin&&s[i].over;//输入终点站
&&&&&&&&cout&&&请输入时间(星期几):&&;
&&&&&&&&cin&&s[i].time;//输入日期
&&&&&&&&cout&&&请输入起飞时间:&;
&&&&&&&&cin&&s[i].starttime;&&//输入起飞时间
&&&&&&&&cout&&&请输入到达时间:&;
&&&&&&&&cin&&s[i].overtime;&&//输入到达时间
&&&&&&&&cout&&&请输入票价:&;
&&&&&&&&cin&&s[i].price;&&&&//输入票价
&&&&&&&&cout&&&请输入票价折扣:&;
&&&&&&&&cin&&s[i].zhekou;&&&//输入票价折扣
&&&&&&&&cout&&&请输入机票数:&&;
&&&&&&&&cin&&s[i].count;//输入机票数
&&&&goto&loop1;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop1:cout&&&是否继续修改?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否继续查找
loop:&Mframe();
void&dingpiao()//定义订票业务函数
ofstream&outfile2;//存储客户信息
outfile2.open(&message.txt&,ios::out);
ofstream&outfile3;
outfile3.open(&hangban.txt&,ios::out);
char&a[10]=&y&;
int&n1,n2;
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&cout&&&请先添加航班信息!&&&endl;
&&&&&&&&&&&&&&&&goto&loop6;
&&&&&&&&&&&&}
cout&&&\n请输入航班号:&&;
cin&&n1;//输入查询的航班号
for(i=0;i&m;i++)
&&&&&if(s[i].num==n1)//按航班号判定输出条件
cout&&&\n您所查找的航班信息为:\n&&;
cout&&&航班号\t起始\t终点\t日期\t起飞\t到达\t票价\t折扣\t机票数\n&;//信息标题
&&&&&&&&&&&&&&&&cout&&s[i].num&&&号\t&&&s[i].start&&&\t&&&s[i].over&&&\t&&&s[i].time&&&\t&&&s[i].starttime&&&\t&&&s[i].overtime&&&\t&&&s[i].price&&&\t&&&s[i].zhekou&&&\t&&&s[i].count&&endl;
&&&&goto&loop;
cout&&&\n对不起,没有您需要的信息!\n&&;
loop:cout&&&是否继续查找?请键入y或n以回车键结束&&;
}while(!strcmp(ii,&y&));//判定是否继续查找
cout&&&请输入你的姓名:&;
&&&&cin&&u[m3].uname;
&&&&cout&&&\n请输入你的证件号码(如:372330********6155):&;
&&&&cin&&u[m3].unumber;
u[m3].dnum=s[i].num;//订单号
cout&&&请输入起飞城市:&;
&loop1:cin&&u[m3].dstartcity;
if(u[m3].dstartcity!=s[i].start)
cout&&&信息输入有误,请重新输入起飞城市:&;
goto&loop1;
cout&&&请输入终点城市:&;
loop2:cin&&u[m3].dovercity;
if(u[m3].dovercity!=s[i].over)
cout&&&信息输入有误,请重新输入终点城市:&;
goto&loop2;
cout&&&请输入日期(星期几):&;
loop3:cin&&u[m3].dtime;
if(u[m3].dtime!=s[i].time)
cout&&&信息输入有误,请重新输入日期(星期几):&;
goto&loop3;
cout&&&请输入起飞时间:&;
loop4:cin&&u[m3].dstarttime;
if(u[m3].dstarttime!=s[i].starttime)
cout&&&信息输入有误,请重新输入起飞时间:&;
goto&loop4;
u[m3].dovertime=s[i].overtime;
u[m3].dprice=s[i].price;
cout&&&请输入您要订的机票数(以回车键结束):&&;
cin&&n;//输入所订机票数
if(n&=0)//判定机票数是否出错
cout&&&输入错误!至少需订1张机票。\n&;
else&if(s[i].count==0)//判定机票是否售完
cout&&&对不起,你所选择的航班的机票已售完!\n&;
else&if(s[i].count!=0&&s[i].count&=n)//判定机票数是否大于等于订票数
s[i].count=s[i].count-n;
u[m3].ucount1=n;
m3++;
cout&&&订票成功!&&;
else&if(s[i].count&n)//判定机票数是否小于订票数
cout&&&对不起,你所选择的航班只剩&&&s[i].count&&&张机票\n&;
cout&&&是否需要重新输入机票数?请输入y或n以回车键结束:&&;//判定是否重新输入订票数
}while(!strcmp(a,&y&));
cout&&&是否需要订其他航班的机票?请输入y或n以回车键结束:&&;
}while(!strcmp(a,&y&));//判定是否继续订票
cout&&&订票完毕!按回车键返回主菜单&&&endl;
for(int&k=0;k&=m3;k++)//保存订单信息
outfile2&&u[k].uname&&&&&&&u[k].unumber&&&&&&&u[k].dnum&&&&&&&u[k].dstartcity&&&&&&&u[k].dovercity&&&&&&&u[k].dtime&&&&&&&u[k].dstarttime&&&&&&&u[k].dovertime&&&&&&&u[k].dprice&&&&&&&u[k].ucount1;
for(int&m5=0;m5&m;m5++)//保存航班信息
&&&&&&&outfile3&&s[m5].num&&&&&&&s[m5].start&&&&&&&s[m5].over&&&&&&&s[m5].time&&&&&&&s[m5].starttime&&&&&&&s[m5].overtime&&&&&&&s[m5].price&&&&&&&s[m5].zhekou&&&&&&&s[m5].count&&endl;
u[m3].dname+=1;
getchar();
getchar();
loop6:&Mframe();
void&tuipiao()//定义退票函数
ofstream&outfile4;
outfile4.open(&hangban.txt&,ios::out);
ofstream&outfile5;
outfile5.open(&message.txt&,ios::out);
int&&m2,n,m1,n1;
char&a[10];
string&mnum;
cout&&&请输入你的证件号码:\n&;
cin&&mnum;
for(int&m=0;m&=m3;m++)
if(mnum==u[m].unumber)
cout&&&******************************&&&endl;
cout&&&*编号:&&&u[m].dname&&&&&&&&&&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].dstartcity&&&----&&&u[m].dnum&&&----&&&&u[m].dovercity&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].dtime&&&&&&&&u[m].dstarttime&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].dprice&&&&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].uname&&&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].unumber&&&&&&&&&&&&&&&&&*&&&endl;
cout&&&******************************&&&endl;
goto&loop4;
cout&&&未找到你的信息!!&&&endl;
&&&&goto&loop5;
loop4:cout&&&信息输出完毕!&&&endl;
cout&&&请输入要退票的航班号:&;
loop2:cin&&m2;//输入要退票的航班号
for(m1=0;m1&=m;m1++)
if(m2==s[m1].num)
i=m1;//记录航班在s[]数组中的位置
for(m1=0;m1&=m3;m1++)//u[]数组
if(m2==u[m1].dnum)n1=m1;goto&loop1;
cout&&&请输入正确的的航班号:&;
goto&loop2;
loop1:cout&&&请输入您要退的机票数目:&&;
loop3:cin&&n;//输入所退票数
if(n&=0)//判定票数是否有效
{cout&&&输入错误!至少需退1张机票。\n请重新输入:&&;
&&&&&goto&loop3;}
else&if(n&u[n1].ucount1)
{cout&&&输入错误!大于你的总票数。\n请重新输入:&;
&&&&&goto&loop3;}
s[i].count=s[i].count+n;
u[m1].ucount1=u[m1].ucount1-n;
cout&&&退票成功!&&;
loop5:cout&&&是否继续?&请键入y或n以回车键结束:&&;//判定是否继续退票
}while(!strcmp(a,&y&));//判定并跳出循环
for(int&m5=0;m5&i;m5++)&&&//保存航班
&&&&&&&outfile4&&s[m5].num&&&&&&&s[m5].start&&&&&&&s[m5].over&&&&&&&s[m5].time&&&&&&&s[m5].starttime&&&&&&&s[m5].overtime&&&&&&&s[m5].price&&&&&&&s[m5].zhekou&&&&&&&s[m5].count&&endl;
for(int&k=0;k&m3;k++)//保存订票信息
outfile5&&u[k].uname&&&&&&&u[k].unumber&&&&&&&u[k].dnum&&&&&&&u[k].dstartcity&&&&&&&u[k].dovercity&&&&&&&u[k].dtime&&&&&&&u[k].dstarttime&&&&&&&u[k].dovertime&&&&&&&u[k].dprice&&&&&&&u[k].ucount1;
cout&&&退票完毕!按回车键返回主菜单&&&endl;
getchar();
void&paixu()//定义排序函数
clock_t&start,&end;
start&=&clock();
quickSort(s,&&0,&i);
end&=&clock();
time1=&end&-&start;
cout&&&&&串行时间:&&&&&time1&&&&endl;
cout&&&排序后的航班信息为:\n&;
output();//显示排序后航班信息
cout&&&\n请按回车键返回上层菜单&&;
&getchar();
&getchar();
void&quickSort(air&A[],&int&first,&int&end)
int&i&=&first,&j&=&end;
if&(first&&&end)
tmp&=&A[first];
while&(i&!=&j)
while&(j&&&i&&A[j].num&&=&tmp.num)
A[i]&=&A[j];
while&(i&&&j&&A[i].num&&=&tmp.num)
i++;
A[j]&=&A[i];
s[i]&=&tmp;
quickSort(A,&first,&i&-&1);
quickSort(A,&i&+&1,&end);
/*void&paixu1()//定义从小到大排序函数
struct&air&t;
for(i=0;i&m;i++)
for(j=i+1;j&m;j++)
if(s[k].num&s[j].num)
s[k]=s[i];
void&paixu2()//定义从大到小排序函数
struct&air&t;
for(i=0;i&m;i++)
for(j=i+1;j&m;j++)
if(s[k].num&s[j].num)
s[k]=s[i];
void&mymessage()&&&//我的信息
string&mnum;
cout&&&请输入你的证件号码:\n&;
cin&&mnum;
for(int&m=0;m&=m3;m++)
if(mnum==u[m].unumber)
if(u[m].ucount1==0)goto&loop3;
cout&&&************************************&&&endl;
cout&&&*编号:&&&u[m].dname&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].dstartcity&&&----&&&u[m].dnum&&&----&&&&u[m].dovercity&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].dtime&&&&&&&&u[m].dstarttime&&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].dprice&&&&&&&&&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].uname&&&&&&&&&&&&&&&&&&&&&*&&&endl;
cout&&&*&&&&&&&&&&&&&&&u[m].unumber&&&&&&&*&&&endl;
cout&&&************************************&&&endl;
goto&loop2;
loop3:cout&&&未找到你的信息!!&&&endl;
loop2:cout&&&信息输出完毕!&&&endl;
cout&&&按回车键返回上一页!&;
getchar();
getchar();
void&save()//定义保存函数
ofstream&hfile;
hfile.open(&hangban.txt&,ios::out);
ofstream&mfile;
mfile.open(&message.txt&,ios::out);
for(i=0;i&m;i++)//逐块保存数据
hfile&&s[i].num&&&&&&&s[i].start&&&&&&&s[i].over&&&&&&&s[i].time&&&&&&&s[i].starttime&&&&&&&s[i].overtime&&&&&&&s[i].price&&&&&&&s[i].zhekou&&&&&&&s[i].count&&endl;
hfile.close();
for(int&k=0;k&m3;k++)//逐块保存数据
mfile&&u[k].uname&&&&&&&u[k].unumber&&&&&&&u[k].dnum&&&&&&&u[k].dstartcity&&&&&&&u[k].dovercity&&&&&&&u[k].dtime&&&&&&&u[k].dstarttime&&&&&&&u[k].dovertime&&&&&&&u[k].dprice&&&&&&&u[k].ucount1;
mfile.close();
void&merge()
int&m&=&0,&n&=&0,&k;
for&(k&=&0;&k&&&i;&k++)
if&(m&&&count_len2&&n&&&count_len1)
if&(b[n].num&&=&c[m].num)
s[k]&=&b[n];
n++;
s[k]&=&c[m];
m++;
if&(m&==&count_len2&||&n&==&count_len1)
if&(m&==&count_len2)
s[k]&=&c[m&-&1];
s[k]&=&b[n&-&1];
k++;
if&(n&&&count_len1)
int&tem&=&count_len1&-&n;
for&(int&p&=&0;&p&&&tem;&p++)
s[k]&=&b[n];
n++;
k++;
else&if&(m&&&count_len2)
int&tem&=&count_len2&-&m;
for&(int&q&=&0;&q&&&tem;&q++)
s[k]&=&c[m];
m++;
k++;
void&jisubi()
clock_t&start,&end;
start&=&clock();
omp_set_num_threads(2);
#pragma&omp&parallel&shared(b,c,count_len1,count_len2)
#pragma&omp&parallel&sections
#pragma&omp&section
quickSort(b,&0,&count_len1&-&1);
#pragma&omp&section
quickSort(c,&0,&count_len2&-&1);
end&=&clock();
time2&=&end&-&start;
cout&&&&&并行时间:&&&&&time2&&&&endl;
6.6.2&执行结果截图
()小数据量验证正确性的执行结果
()大数据量获得较好加速比的执行结果
&&理论加速比:1.9
6.6.3&遇到的问题及解决方案
&&&遇到的问题就是输入数据很少时,所需时间都为零或者加速比不明显。
&&&&由于电脑配置比较先进,运算能力很强。
解决方法:
&&加大数据量。
排名:千里之外
(5)(1)(3)(3)(0)(1)(11)(1)(5)(2)(1)

我要回帖

更多关于 mpi并行编程入门 的文章

 

随机推荐