当前位置: 首页 > news >正文

高性能计算之MPI:第一次MPI并行程序设计练习

第一次MPI并行程序设计练习

第一题:定积分计算

题目要求:

设计MPI并行程序,计算定积分:f010xdxf_{0}^{10}\sqrt{x}dxf010xdx

解题思路:

这题非常简单,首先我们设定有 n 个进程分任务并行完成这个计算需求。每个进程要计算 m 个小曲边梯形的面积。然后规定除了 0 进程以外的进程把计算的结果发给 0 进程,然后再由 0 进程统一把计算的部分结果加起来就是整个定积分的值了!

怎么计算曲边梯形的面积呢?稍微啰嗦一下下,假设当前进程的秩是 rank,那么这个进程处理的区间的左边界一定是:rank * m,然后在该进程下,每次计算的曲边梯形的高h = f((rank * m + k) * w + w / 2),这个f(x)也就是被积函数!这个 w 也就是每个进程处理的区间的每个小曲边梯形的步长,也就是人家的底边。每次我们计算小曲边梯形的底边中点对应的高,就是 h了!然后累积它们即可!

解题代码:

#include<mpi.h>#include<stdio.h>#include<stdlib.h>#include<math.h>doublef(doublex){returnsqrt(x);// f(x) = sqrt(x)}intmain(intargc,char**argv){intrank,size;doubles=0.0,t=10.0;MPI_Init(&argc,&argv);MPI_Comm_rank(MPI_COMM_WORLD,&rank);MPI_Comm_size(MPI_COMM_WORLD,&size);intpro_num=size;intper_num=10000,k;doublew=(t-s)/(1.0*pro_num*per_num);doublepart_num=0.0,x;for(k=0;k<per_num;++k){x=s+(1.0*rank*per_num+k)*w+w/2.0;part_num+=f(x)*w;}if(0!=rank){MPI_Send(&part_num,1,MPI_DOUBLE,0,rank,MPI_COMM_WORLD);}else{intj=0;doubleresult=part_num;doubletemp_res;for(j=1;j<size;++j){MPI_Recv(&temp_res,1,MPI_DOUBLE,j,j,MPI_COMM_WORLD,MPI_STATUSES_IGNORE);result+=temp_res;}printf("The result is : %.3lf\n",result);}MPI_Finalize();return0;}

解题结果:

解题感悟:

这题还是比较easy的,相比课题上那不是人的seidel迭代、超松弛迭代……这个还算非常友好!

不过需要注意的是,这个Linux里头啊,编译带有 math.h 的数学库,需要在后面加一个参数 -lm 来告知编译器你用了 math 库!

第二题:计算圆周率PI(定积分拓展)

题目要求:

想办法计算圆周率PI,要用MPI并行程序设计!

解题思路:

已知PI = arctan(1) * 4,于是有下列计算PI的公式:

π=4∗f0111+x2dx\pi = 4 * f_{0}^{1}\frac{1}{1 + x^2}dxπ=4f011+x21dx

这样就和上面第一题完全一样的啦,就不多解释了,直接上代码吧!

解题代码:

#include<mpi.h>#include<stdio.h>#include<stdlib.h>doublef(doublex){// f(x) = 1/(1 + x^2)return(1.0/(1+x*x));}intmain(intargc,char**argv){intrank,size;doubles=0.0,t=1.0;MPI_Init(&argc,&argv);MPI_Comm_rank(MPI_COMM_WORLD,&rank);MPI_Comm_size(MPI_COMM_WORLD,&size);intpro_num=size;intper_num=100000,k;doublew=(t-s)/(1.0*pro_num*per_num);doublepart_num=0.0,x;for(k=0;k<per_num;++k){x=s+(1.0*rank*per_num+k)*w+w/2.0;part_num+=f(x)*w;}if(0!=rank){MPI_Send(&part_num,1,MPI_DOUBLE,0,rank,MPI_COMM_WORLD);}else{intj=0;doubleresult=part_num;doubletemp_res;for(j=1;j<size;++j){MPI_Recv(&temp_res,1,MPI_DOUBLE,j,j,MPI_COMM_WORLD,MPI_STATUSES_IGNORE);result+=temp_res;}result*=4;printf("The result is : %.3lf\n",result);}MPI_Finalize();return0;}

解题结果:

解题感悟:

本题的做法理应非常多!
还可以去做级数,因为PI = cos(-1) = ……(级数的表示)
所以还可以分任务,并行计算这个级数,然后近似得到结果!

第三题:环形乒乓球

题目要求:

乒乓球是一项双人运动,要求是A发球,随后B接球……如此循环往复!

要求利用MPI并行程序设计,得到两个计算节点(或者是同一计算节点下的两个进程),并行完成接球与发球,做到两个进程双方来回打乒乓球!一定要是A发完球B才能接球,B发球时A同理!

解题思路:

两方发球接球倒是很简单的事情,只需要两个进程并行完成消息传递即可!

但是后面的要求是要A完成发球B才能接球,由于程序的运行、内存的分配在不同的两个进程中是相互独立的!所以可能出现A一直调度而B比较慢,又无法抢占调度!

出现A连续发球好几次B才接到球这样的情况,所以我们用Sleep()的方式处理,要求A在发球后立刻进入阻塞队列,好让B有机会调度,等到B发球的时候同理!

解题代码:

#include<mpi.h>#include<stdio.h>#include<unistd.h>intmain(intargc,char**argv){MPI_Init(NULL,NULL);intworld_size;MPI_Comm_size(MPI_COMM_WORLD,&world_size);intworld_rank;MPI_Comm_rank(MPI_COMM_WORLD,&world_rank);if(2!=world_size){fprintf(stderr,"error: must have two process in %s \n",argv[0]);MPI_Abort(MPI_COMM_WORLD,1);}intLIMIT=10,count=0,tag1=0,tag2=0;while(count<LIMIT){if(tag1==tag2)MPI_Barrier(MPI_COMM_WORLD);if(world_rank==1){MPI_Recv(&count,1,MPI_INT,0,tag2,MPI_COMM_WORLD,MPI_STATUS_IGNORE);tag2++;printf("1 process received %d from 0 process\n",count);sleep(1);count++;MPI_Send(&count,1,MPI_INT,0,tag2,MPI_COMM_WORLD);}else{count++;MPI_Send(&count,1,MPI_INT,1,tag1,MPI_COMM_WORLD);tag1++;MPI_Recv(&count,1,MPI_INT,1,tag1,MPI_COMM_WORLD,MPI_STATUS_IGNORE);printf("0 process received %d from 1 process\n",count);sleep(1);}}MPI_Finalize();return0;}

解题结果:

这里我们就可以看到,我们做到了每一轮收到的一方都是上一轮发球的一方!

解题感悟:

自认为这题我做的很糟糕!!!!

因为我采用这种强行阻断进程,强行让进程进入阻塞队列的Sleep()函数,导致了效率非常底下!!!!

希望各位前辈大佬带带刚刚入门高性能计算的小弟,教教我有无高效的做法完成这种来回进程调度!!!!

http://www.gsyq.cn/news/1633028.html

相关文章:

  • 有符号和无符号0按位取反的区别
  • Windows 开启 IIS 服务
  • MLOps实战:构建可观测、弹性、可治理的机器学习生产系统
  • 野数据处理实战:构建五层韧性物联网数据流水线
  • 关于const、指针和引用【C++复习】
  • CAPL脚本函数不能返回数组的替代方案
  • 三步搞定跨语言障碍:STranslate翻译工具完全指南
  • Springboot整合MybatisPlus【一】
  • 赞赞赞!融云收获行业媒体「组团打 Call」
  • Elm-platform项目管理指南:使用elm-package管理依赖和发布包
  • STM32F107VC与A89307的BLDC电机FOC控制方案详解
  • 3个平台限制下的架构突破:猫抓项目的技术演进启示
  • 10分钟上手NoDock:Node.js开发者必备的Docker容器化解决方案
  • Scarab:让空洞骑士模组管理变得直观简单的跨平台解决方案
  • 酷睿Ultra X9 388H架构解析与性能实测
  • YOLO26实战:从环境搭建到自定义训练的全流程避坑指南
  • gprMax devel分支中的重构:从过程式仿真程序到分层科学计算框架
  • 如何高效提取Wallpaper Engine资源:专业逆向工具的完整指南
  • Slash实战案例:从代码示例到真实项目,教你如何优雅实现复杂富文本界面
  • 省时省力!德国宣誓翻译驾照认证件去哪办?24小时出件全攻略
  • MZmine 3终极指南:如何免费快速处理质谱数据的完整解决方案
  • DocStrap社区贡献指南:如何参与项目开发与问题修复
  • cdc同步工具
  • Tabled API集成指南:如何将表格提取功能嵌入到你的应用中
  • AI大模型驱动自动化测试:从原理到落地的全链路实践指南
  • 【Java课程设计/毕业设计】基于 SpringBoot 的数字科技风险报告管理系统的设计与实现智能化科技风险报告编制与溯源管理系统【附源码、数据库、万字文档】
  • Micro Journal Rev.7电子墨水屏版本:护眼写作的革命性突破
  • 融云「北极星」数据监控平台:数据可视通晓全局,精准分析定位问题
  • Instatic媒体批量上传:拖放功能与进度监控的终极指南
  • 陶瓷基板在PCB设计中的核心价值与应用解析