一个简单的pingpong程序测试mpi消息通讯的开销及并行计算通讯启动时间测算

一个简单的pingpong程序测试mpi消息通讯的开销

随着科技的进步,集群单节点计算能力的提高,似乎通讯开销成了并行计算中dominant,再提高计算能力对于并行的增益似乎效果不明显,限制性能的瓶颈从处理器计算能力上转移到通讯开销上。显然,此时设法降低MPI消息通讯带来的时间消耗,成为了当务之急。

因此,写了一个极其简单的pingpong并行程序来测试消息通讯带来的开销。

基本思想

所谓的pingpong,顾名思义就是找一个数据包不断地在两个节点之间丢来丢去,想打乒乓球一样。
我们在程序中定义两重循环,外重循环定义数据量大小,从1kb到100m,涨幅为100kb,内层循环对于每一固定大小的数据跑100个来回,最后取平均值,作为这个大小的数据的传输时间。最后,以数据量大小为横轴,时间为纵轴,plot一下。

准备工作

我们连接了机房的两台电脑,作为实验环境。主要设置了SSH免密登录和NFS共享目录。
一个简单的代码如下:

/*** pingpong程序,用于测试点点传送的速度*/
//32位系统中,一个int占4B(sizeof(int)),1KB=250int,1M=250000int
//1M=1000kb,100M = 10e5kb
//使用N表示数据量大小为 N kb
//程序运行时,首先要把目录下的data.txt删除
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <string.h>//#define N 4 //外层循环数据量大小改变,使用动态数组来实现
#define m 100 //定义pingpong的回合
#define debugflag 0int main (int argc, char *argv[]) {int myrank,i,nprocs;double pingpongSize,aver_tcost,total_t,Ts[m];double st, et, time_cost;double N, Num_int;int *pingpong;char file_name[10];MPI_Init(&argc, &argv);//初始化MPI环境MPI_Comm_size(MPI_COMM_WORLD, &nprocs);//获取总进程数MPI_Comm_rank (MPI_COMM_WORLD, &myrank);//获取本地进程编号MPI_Status status;//int opposite_rank;  opposite_rank = (myrank == 0) ? (1) : (0);FILE *fp;sprintf(file_name,"data_from_rank%d.txt",myrank);fp=fopen(file_name,"w+");//   for(N=1; N<=1e4; N=N+1e3) {for(N=1e-3; N<=1e5; N=N*2){total_t = 0.0;pingpong = (int*)malloc( N*1000);//开辟 N kb的内存Num_int = ( N*1000)/sizeof(MPI_INT);if(!pingpong) {printf("创建pingpong失败!\n");exit(1);}//  int pingpong[N] = {0};//随便赋值for(i=0;i<Num_int;i++){pingpong[i] = 999;//赋值,并非必要//     printf("%d,%d",i,pingpong[i]);}// pingpong[0] = 999;if(myrank==0){printf("开始 %lfkb/1e5kb 数据传送……\n",N);}for(i=0; i<m; i++) {MPI_Barrier(MPI_COMM_WORLD);//同时开始计时st = MPI_Wtime();if(myrank==0) {MPI_Send (pingpong, Num_int, MPI_INT, 1, i, MPI_COMM_WORLD);
#if debugflag   printf("第%d回合:%d发送数据完成……\n",i+1,myrank);
#endif}if(myrank==1) {MPI_Recv (pingpong, Num_int, MPI_INT, 0, i, MPI_COMM_WORLD, &status);MPI_Send (pingpong, Num_int, MPI_INT, 0, i, MPI_COMM_WORLD);
#if debugflag               printf("第%d回合:%d接收和发送数据完成……\n",i+1,myrank);
#endif              }if(myrank==0) {MPI_Recv (pingpong, Num_int, MPI_INT, 1, i, MPI_COMM_WORLD, &status);
#if debugflag               printf("第%d回合:%d接收数据完成……\n",i+1,myrank);printf("第%d回合succeed! The time of cost is %lf\n\n",i+1,time_cost);//          printf("一个int占用:%ld B",sizeof(myrank));
#endif  }MPI_Barrier(MPI_COMM_WORLD);//保证进程1计算的时间也准确et = MPI_Wtime();time_cost = et-st;total_t = total_t+time_cost;Ts[i] = time_cost;}aver_tcost = total_t/m;pingpongSize = N/1e3;//单位换算成M// printf("%lf个int的数据量大小为%lf M!\n",N,pingpongSize);fprintf(fp,"%lf,%lf\n",pingpongSize,aver_tcost);free(pingpong);if(myrank == 0){printf("%lfM 数据包发送接收回合完成……\n",pingpongSize);printf("%lfkb 的数据量的传送时间平均时间为: %lf \n\n",N,aver_tcost);}}fclose(fp);MPI_Finalize ();//结束MPI环境return 0;
}

实验和结果

将实验结果,画一下图,如下:

从结果上可以看到,整体上看,通讯开销随着数据量大小呈现一个的关系,我们可以很容易地用线性函数去做线性fit,得到了T = 0.01711X+0.0004188这个这样一个关系,可靠程度:误差平方和为4.79e-6,均方根误差为0.0003263,确定系数约为1,说明这个拟合是很可靠的。
分析一波这个拟合结果,我们大概能知道每增加100m的数据,大概需要增加1.7s。所以,100M的数据,跑一百个回合,大概需要三分钟。

并行计算通讯启动时间测算

简述

我们知道,并行计算的消息传递不可能一上来就开始传数据,它是有一个启动时间的,就像游泳前的热身。那么这个启动时间是多少呢?又该怎么测算呢?
依然是pingpong的例子,只不过为了看出1kb之前的这个微小的数据变化段通讯时间情况,我修改了程序中数据量大小增加的情况,前面以double的形式从1B增加到1KB,往后,以5M为间隔,逐渐将数据量增加到100M。

数值实验

分别测定了双节点,和单节点的情况,结果如下。

双节点

首先使用两台节点跑了这个程序。
为了看到初始的那一小段的情况,我们将绘制的plot图(近似线性)在开始断不断地放到,最后发现,通讯时间在1kb左右的地方开始激增。

从图上,我们可以看出,最开始的一段有一个抖动,这是意外。为了更好地体现这种通讯时间前面一小段几乎水平不变,后面呈线性增长的这种“拐角”情况,我们不妨来画一下双log图来呈现。为什么用双log图呢?很容易想到,如果趋势是线性的,那么双log后,展现出来还是线性的,如果是常数关系,那么双log后还是常数关系。log函数能使数据在展现上变得更加均匀,避免了“头重尾轻,细节模糊”的情况。双log函数,能够将细节的地方的展现和刻画出来,结果如下。

可以看得出来,开始一段时间的通讯时间几乎没有改变,通讯启动时间大概为0.000165s,即0.165毫秒。

单节点

对于单节点,不涉及两台机器的通讯,我们重复了上面的测算过程,结果如下:

上面直接plot的图之后再方法局部的图,发现有一个比较反常的点,估计是跑程序的时候,受到了别的因素的干扰。如果去掉这个离群点来考虑,它也是有这样一种“前平后翘”的“对勾”走势。我们再来看看双log图。

双log图使数据呈现得更加“集中”,也使得原来离群得厉害的点变得那么不靠谱。从这里,因为开始时相对比较平坦(排除其他因素影响的情况下),我们假设开始那一段没有增长,姑且就可以把开始那段的值作为程序的启动开销。这里,可以看到,单击上,并行程序运行时,启动的开销大概为2e-6s,即0.002ms,基本上是两台机子通讯启动的百分之一。

由那些不正常抖动的情况来看,并行对于资源的要求还是很敏感的,比如说当你在跑程序时,有其他资源抢占了资源,就容易造成通讯开销的增加。

一个简单的pingpong程序测试mpi消息通讯的开销及并行计算通讯启动时间测算相关推荐

  1. 如何编写一个简单的 Python 程序

    本教程将教你如何编写一个简单的 Python 程序.我们将从解释 Python 程序是什么开始,然后继续讨论语法的各个方面,即语言的结构. 什么是 Python? Python是一种越来越受欢迎的编程 ...

  2. 第一章 开始 |编写一个简单的C++程序

    学习目标: 编写一个简答的C++程序 学习内容: 1.一个简单的c++程序 2.输入和输出 3.关于注释 4.控制流 5.类简介 6.书店程序 1.1 编写一个简单的c++程序 每个C++程序都包含一 ...

  3. C语言实现的一个简单的HTTP程序

    以下是参考<winsock网络编程经络>中讲解web应用http协议的时候,实现的一个简单的http程序,包含一个服务器和一个客户端. 先贴上客户端的程序:   /************ ...

  4. 通信软件基础B-重庆邮电大学-Java-编程实现一个简单的聊天程序-多线程编程实现

    实验任务六 编程实现一个简单的聊天程序-多线程编程实现 1. 系统设计要求 编程实现一个简单的聊天程序,实现两台计算机间的信息交互,使用多线程编程实现:可同时连接多个客户端,服务器收到客户端发送的消息 ...

  5. 利用python实现一个简单的表白程序

    见过各种各样的表白方式,也听到过很多种表白方式,什么文科生式表白.理科生式表白呀,今天教你程序员的表白,咱们今天写一个简单的表白程序. 话不多说直接上教程 首先我们老样子先导入系统文件库 from t ...

  6. Win32 程序开发:一个简单的Win32程序

    1)什么是Win32 Win32是指Microsoft Windows操作系统的32位环境,与Win64 都为Windows常见环境.如今的Win32操作系统可以一边听音乐,一边编程,一边打印文档.W ...

  7. 使用Hprose制作一个简单的分布式应用程序

    2019独角兽企业重金招聘Python工程师标准>>> 使用Hprose制作一个简单的分布式应用程序只需要几分钟的时间.本文将用一个简单的实例来带您快速浏览使用Hprose for ...

  8. 创建一个简单的应用程序窗口,显示“欲穷千里目 更上一层楼”。这一行文字从窗口中向左滚动显示,而且每显示一轮,改变一次颜色,改变一次字体,一个周期为4种颜色,分别为红、绿、黄、蓝,四种字体分别为宋体、楷

    创建一个简单的应用程序窗口,显示"欲穷千里目 更上一层楼".这一行文字从窗口中向左滚动显示,而且每显示一轮,改变一次颜色,改变一次字体,一个周期为4种颜色,分别为红.绿.黄.蓝,四 ...

  9. DuiVision开发教程(2)-如何写一个简单的界面程序

    基于DuiVision界面库开发的界面程序主要包括如下几部分内容: 1.资源定义,包括图片资源.各个窗口界面的xml定义文件 2.事件处理类代码,用于处理界面响应消息 3.其他业务逻辑代码 下面举例说 ...

最新文章

  1. 分析无线充电线圈产生的导航信号在自绕工字型电感中的感应电动势
  2. htmlparser操作bean类提取html页面元素
  3. Android四大组件ContentProvider
  4. SpringBoot项目遇到的一些问题
  5. HDU 2222 ac自动机模板
  6. 光敏电阻控制led亮度程序_单片机开发系统学习LED亮度控制原理
  7. TensorFlow+pytorch+gpu+anaconda极简安装教程
  8. 转:js中arguments详解
  9. 学术墙报模板_【征集】|复旦大学2019博士生学术论坛之生命科学论坛墙报展
  10. 一个屌丝程序猿的人生(四十九)
  11. arduino c语言pdf,arduino编程从零开始
  12. 学好英语对IT软件工程师的影响
  13. LayUI表单验证select定位失效问题
  14. 如何开发网页3D游戏
  15. ios safari 模拟器_电脑也能运行iOS iOS模拟器体验
  16. 摆球控制程序PID算法
  17. 正版Windows7 OEM初级版升级到各版本(Lenovo/ThinkPad/ThinkCentre品牌)的密钥
  18. 第145章 SQL函数 TO_NUMBER
  19. 从零开始自制实现WebServer(十九)---- 正式系统的学习一下Git 捣鼓捣鼓github以及一些其他的小组件
  20. 基于Ubuntu系统,调用opencv在图片上显示数字和汉字

热门文章

  1. JAVA的反射机制==用反射分析类的实现
  2. 搜狗输入法更换字体与皮肤
  3. 魔鬼R包—SNPassoc的下载与安装
  4. 计划赶不上变化,为什么还要计划呢?
  5. 8.node多进程之spawn
  6. 印度洋重建及东经九十度海岭
  7. 《从两月失败职场经历看内部创业四大弊病》有感
  8. android 的injustdecodebounds
  9. Oracle(二)Oracle sql操作
  10. mac上打开chm文件