目录
前面几节我们已经介绍了MPI的基本情况,包括编程模型、并行算法、常用的MPI接口以及MPI通信规则、数据类型等。接下来通过实现简单的MPI程序来了解MPI接口的使用和程序设计思路。
一、MPI实现计时功能
科学与工程计算程序中,会经常需要统计计算时间来评估并行计算效率。MPI程序中经常用到时间函数,比如根据时间的不同选取不同的随机数种子,或者根据时间的不同对程序的执行进行控制等。MPI中提供了计时接口MPI_WTIME()、MPI_WTICK()。
1、MPI_WTIME()
MPI_WTIME()
//c语言的说明
double MPI_Wtime(void)
//Fortran语言的说明
DOUBLE PRECISION MPI_WTIME()
MPI_WTIME返回一个用浮点数表示的秒数,表示从过去某一时刻到调用时刻所经历的时间。这样如果需要对特定的部分进行计时,可以采取如下的方式:
double startime, endtime;
...
startime = MPI_Wtime();
{
//需要计时的代码部分
}
endtime = MPI_Wtime();
printf("The run time is %f seconds.\n",(endtime - startime);
2、MPI_WTICK()
MPI_WTICK返回MPI_WTIME的精度,单位是秒,可以将其看作是一个时钟滴答所占用的时间。
MPI_WTICK()
//c语言的说明
double MPI_Wtick()
//Fortran语言的说明
DOUBLE PRECISION MPI_WTICK()
3、示例
下面程序调用了MPI计时函数。
if((t2 - t1) > 5.0)
i = 9; //如果两次计时得到的时间间隔过大,则改变循环计数变量的值,迫使程序从循环退出
}
//若计时函数正确,则不需要循环10次程序即退出,否则会重复执行到10次
if(i == 10)
{
printf("Timer around sleep(1) did not give 1 second, gave %f.\n",(t2 - t1));
err++;
}
else
printf("MPI_Wtime is OK!\n");
//得到一个时钟滴答时间
tick = MPI_Wtick();
if(tick > 1.0 || tick < 0.0)
{
//时间太长或者为负数,则该时间不正确
err++;
printf("MPI_Wtick gave a strange result: %f.\n",tick);
}
else
printf("MPI_Wtick is OK!\n");
MPI_Finalize();
return 0;
}
编译及运行结果如下:
二、获取机器名字和MPI版本号
1、MPI_GET_PROCESSOR_NAME()
通常我们在使用MPI编写程序时,会遇到需要将一些中间结果或最终结果输出到程序自己创建的文件中,对于在不同机器上的进程,常希望输出的文件名包含该机器名,或者需要根据不同的机器执行不同的操作,这时仅依靠进程标识rank号是不够的,MPI提供了一个接口MPI_GET_PROCESSOR_NAME(),可以使各个进程在运行时动态的获取该进程所运行机器的名字。
MPI_GET_PROCESSOR_NAME(name, resultlen)
OUT name 当前进程所运行的机器名
OUT resultlen 返回名字的长度(以可打印字符的形式)
//c语言的说明
int MPI_Get_processor_name(char *name, int *resultlen)
//Fortran语言的说明
MPI_GET_PROCESSOR_NAME(NAME, RESULTLEN, IERROR)
CHARACTER*(*) NAME
INTEGER RESULTLEN, IERROR
2、MPI_GET_VERSION()
同时,MPI提供了可以返回MPI版本号的接口MPI_GET_VERSION。
MPI_GET_VERSION(version, subversion)
OUT version 主版本号
OUT subversion 次版本号
//c语言的说明
int MPI_Get_version(int *version, int *subversion)
//Fortrna语言的说明
MPI_GET_VERSION(VERSION, SUBVERSION, IERROR)
INTEGER VERSION, SUBVERSION, IERROR
3、示例
program main
include 'mpif.h'
character*(MPI_MAX_PROCESSOR_NAME) name
integer resultlen, version, subversion, ierr
call MPI_INIT(i