科学计算导论
科 学 计 算 导 论
实验指导书
高性能计算实验室:刘涛、赵冬梅
西南科技大学 计算机科学与技术学院
2018 年 08 月
1
科学计算导论
实 验 指 导 书
实验一 并行计算-MPI
实验目的:
初步了解并行计算的概念,能够在 Windows 平台上安装 MPI 库(OpenMPI
或者 MPICH2),并掌握在 Visual studio 中调用 MPI 头文件的方法;初步掌握使用
MPI 编制并行程序的步骤与核心函数的意义及其参数的含义。
实验内容:
(1)介绍并行计算消息接口 MPI 的定义、应用背景与基本概念;
(2)在教师指导下在 Windows 系统上安装 MPI,(鼓励学生在 Linux 操作系
统上安装以及完成实验);
(3)教师讲解 MPI 程序编制的基本步骤,演示基于 MPI 的两个演示程序;
(4)在教师指导下,学生完成基于 MPI 的两个演示程序(鼓励学生添加入
其他基于 MPI 的功能),完成相应的实验报告。
实验环境:
Windows 7 及以上操作系统,32/64 位系统均可,推荐 64 位;程序开发环境
要求 Microsoft Visual Studio 2008 及以上,MPI 要求为:MPICH2;硬件要求为:I3
及以上的多核 CPU(对应 AMD 多核处理器亦可)。
【备注】:估计学生在 Linux 系统上完成实验,可根据学生自己的兴趣与爱
好选择 Linux 版本。
实验介绍:
MPI 是一个跨语言的通讯协议,用于编写并行计算机。支持点对点和广播。
MPI 是一个信息传递应用程序接口,包括协议和和语义说明,它们指明其如何在
各种实现中发挥其特性。MPI 的目标是高性能,大规模性,和可移植性。MPI 在
今天仍为高性能计算的主要模型。
常见的 MPI 实现包括 OpenMPI,MPICH 等,可在不同平台上实现 MPI 的并
行通信,常见的 MPI 函数如下:
1. Mpi_init()初始化 MPI 执行环境,建立多个 MPI 进程之间的联系,为
后续通信做准备;
2. Mpi_finalize 结束 MPI 执行环境;
2
科学计算导论
3. Mpi_comm_rank 用来标识各个 MPI 进程的,给出调用该函数的进程的进
程号,返回整型的错误值。两个参数:MPI_Comm 类型的通信域,标识参
与计算的 MPI 进程组; &rank 返回调用进程中的标识号;
4. Mpi_comm_size 用来标识相应进程组中有多少个进程;
5. Mpi_send(buf,counter,datatype,dest,tag,comm): buf:发送缓冲区的起始
地址,可以是数组或结构指针;count:非负整数,发送的数据个数;
datatype:发送数据的数据类型;dest:整型,目的的进程号;tag:整
型,消息标志;comm:MPI 进程组所在的通信域。
a) 含义:向通信域中的 dest 进程发送数据,数据存放在 buf 中,类型是
datatype,个数是 count,这个消息的标志是 tag,用以和本进程向
同一目的进程发送的其它消息区别开来。
6. Mpi_recv(buf,count,datatype,source,tag,comm,status): source:整型,接
收数据的来源,即发送数据进程的进程号; status:MPI_Status 结构指
针,返回状态信息。
此外,还包括如下定义或函数:
数据类型和预定义的量
用于作为参数的数据类型 MPI_INT, MPI_DOUBLE, MPI_CHAR, MPI_Status
预定义的量 MPI_STATURS_IGNORE, MPI_ANY_SOURCE, MPI_ANY_TAG
集合通信
MPI_Bcast 广播,使得数据有 p 份拷贝
MPI_Scatter 散发,每份数据只拷贝一次
MPI_Gather 收集,每份数据只拷贝一次
MPI_Reduce 归约
点到点通信函数
MPI_Barrier(communicator)来完成同步
MPI_Bsend(message_data, size, data_type, dest_id, tag, communicator) 来 发
送数据,需要预先注册一个缓冲区,并调用 MPI_Buffer_attach(buffer, buf_size)来
供 MPI 环境使用
MPI_Buffer_attach(buffer, size)来把缓冲区 buffer 提交给 MPI 环境,其中 buffer
是通过 malloc 分配的内存块。
MPI_Buffer_detach(&buffer,&size)来确保传输的完成,尽量把 detach 和 attach
函数配对使用,正如尽可能同时使用 malloc 和 free,同时使用 Init 和 Finalize,
防止遗漏!
MPI_Pack_size(size, data_type, communicator, &pack_size)来获取包装特定类
型的数据所需要的缓冲区大小(还没有计入头部,所以真正缓冲区大小 buf_size =
MPI_BSEND_OVERHEAD + pack_size,如果有多份数据发送,则 buf_size 还要叠加)。
使用 MPI_Recv(message, size, data_type, src_id, tag, communicator, status)来
接收数据,把已经到达接收缓冲区的数据解析到 message 数组中,只有全部数据
都解析出来时,函数才返回。
获取当前时间
double MPI_Wtime(void) 取 得 当 前 时 间 , 计 时 的 精 度 由 double
MPI_Wtick(void) 取得。作为对比,一般在 C/C++中,插入 time.h,通过 clock_t
clock(void) 取得当前时间,计时的精度由常数 CLOCKS_PER_SEC 定义。
演示程序 1:
3
科学计算导论
传统 C/C++程序学习中第一个程序为“Hello world!”,此实验中首先给出
C/C++语言的实现版本;如下
C 语言版:
#include
int main(void)
{
}
/*下面要输出hello world*/
printf("hello world!");
return 0;
C++语言版:
#include "iostream"
using namespace std;
int main(void)
{
}
cout<<"hello word!"<
#include
int main(int argc, char * argv[])
{
}
int myrank, nprocs;
// 初始化MPI环境
MPI_Init(&argc, &argv);
// 获取当前进程在通信器MPI_COMM_WORLD中的进程号
MPI_Comm_size (MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
printf("Hellow, world! %dth of totalTaskNum = %d\n", myrank, nprocs);
MPI_Finalize();
return 0;
得到的输出结果如下:
4
科学计算导论
MPI+C++语言版:
#include"mpi.h"
#include
using namespace std;
int main(void){
int rankID;
int sizeNum;
MPI_Init(0,0);
MPI_Comm_size(MPI_COMM_WORLD, &sizeNum);
MPI_Comm_rank(MPI_COMM_WORLD, &rankID);
cout<<"Hello world! "<
#include
int _tmain(int argc, _TCHAR* argv[])
{
int myrank, nprocs, name_len, flag;
double start_time, end_time;
5
科学计算导论
char host_name[20];
MPI_Initialized(&flag);
fprintf(stderr, "flag:%d/n", flag);
MPI_Init(0,0);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Get_processor_name(host_name, &name_len);
if (myrank == 0)
{
fprintf(stderr,"Precision of MPI_WTIME(): %f.\n",MPI_Wtick());
fprintf(stderr,"Host Name:%s\n",host_name);
}
start_time = MPI_Wtime();
Sleep(myrank * 3);
end_time = MPI_Wtime();
fprintf(stderr, "myrank: %d. I have slept %f
seconds.\n",myrank,end_time-start_time);
MPI_Finalize();
return 0;
}
结果如下图所示:
6
科学计算导论
实验步骤:
【备注】:在编译完成含 MPI 代码的程序之后,直接运行该程序,依然会出
现与无 MPI 代码的程序一样的结果,需要调用 mpiexec 命令来指定运行生成的可
执行文件,具体格式如下(Windows 系统中需要调用 cmd 终端界面):
Mpiexec –n 8 xx.exe
需要注意的是,如果未在系统环境变量中指定 mpiexec 的路径,则需要在命
令行中给出该命令的路径形式,“-n”则是指定多少个进程数,“xx.exe”则是自
己编译得到的可执行文件名。
实验要求:
(1)独立完成两个演示程序。
(2)独立完成实验报告,给出在操作系统上安装 MPI 的详细过程,以及实
现的代码,着重分析 MPI 并行程序的优势以及可能的应用领域、普通 C/C++程序
与 MPI 程序的区别,在实验报告中应给出程序运行的结果截图。
7
科学计算导论
实验二 MPI 程序设计
实验目的:
在第一个实验的基础上,采用 MPI 完成对于连续函数 f(x)的从起始位置到终
止位置的面积积分,采用梯形计算近似面积。要求能够深入理解近似积分求面积
的方法,掌握采用传统串行方法计算近似面积积分的方法,初步掌握 MPI 中消
息传递机制(MPI_Send 和 MPI_Recv),能够理解采用 MPI 并行求解面积积分的
思路和方法。
实验内容:
(1)理解近似积分求面积的方法;
( 2 ) 采 用 传 统 串 行 方 法 计 算 =3.0+2.345∗+0.98372∗2+
0.3221∗3的指定区域面积,记录求解所消耗的时间(要求在不少于 10 种不同
(3)采用 MPI 方法计算 =3.0+2.345∗+0.98372∗2+0.3221∗3
的指定区域面积,记录求解所消耗的时间(要求在不少于 10 种不同插样值下比
较,该 10 种插样值与步骤(2)种保持一致);
插样值下比较);
(4)通过图表的方式对比两种方式的时间消耗曲线图,分析其背后的影响
因素,分析两种版本计算得到的面积值为何存在差异。
实验环境:
Windows 7 及以上操作系统,32/64 位系统均可,推荐 64 位;程序开发环境
要求 Microsoft Visual Studio 2008 及以上,MPI 要求为:;硬件要求为:I3 及以上
的多核 CPU(对应 AMD 多核处理器亦可)。
【备注】:鼓励学生在 Linux 系统上完成实验,可根据学生自己的兴趣与爱
好选择 Linux 版本。
实验示范代码:
要求的实验步骤如下:
(1)传统串行代码
LARGE_INTEGER now;
LARGE_INTEGER then;
LARGE_INTEGER fr;
double estimat = 0.0;
double delta = 0.0;
const int fre = 50000000;
//int myrank, nprocs,flag;
8