|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
对于基本的应用,MPI同其它消息传送系统一样易于使用。下面的样本代码包含了用于动态负载平衡的主/从应用的全部通信框架。下面的代码描述了一些编写典型并行应用程序所需的函数。
#include <mpi.h>
#define WORKTAG 1
#define DIETAG 2
main(argc, argv)
int argc;
char *argv[];
{
int myrank;
MPI_Init(&argc, &argv); /* MPI 初始化 */
MPI_Comm_rank(
MPI_COMM_WORLD, /* 总使用 */
&myrank); /* 进程标识数,0到N-1 */
if (myrank == 0) {
master();
} else {
slave();
}
MPI_Finalize(); /* MPI 结束*/
}
master()
{
int ntasks, rank, work;
double result;
MPI_Status status;
MPI_Comm_size(
MPI_COMM_WORLD, /* 总使用 */
&ntasks); /* #应用程序中的进程 */
/*
* Seed the slaves.
*/
for (rank = 1; rank < ntasks; ++rank) {
work = /* get_next_work_request */;
MPI_Send(&work, /* 消息缓冲区 */
1, /* 一个数据项 */
MPI_INT, /* 数据项是整数 */
rank, /* 目的进程标识数 */
WORKTAG, /* 用户所选的进程标识 */
MPI_COMM_WORLD);/* 总使用 */
}
/*
* 从任意从属进程接收结果,同时分派新工作
* 工作请求已用尽
*/
work = /* 得到下一个工作请求 */;
while (/* 有效的新工作请求 */) {
MPI_Recv(&result, /* 消息缓冲区 */
1, /* 一个数据项 */
MPI_DOUBLE, /* 双精度实类型 */
MPI_ANY_SOURCE, /* 从任意发送者接受 */
MPI_ANY_TAG, /* 任意消息类型 */
MPI_COMM_WORLD, /* 总使用 */
&status); /* 所接受的消息信息 */
MPI_Send(&work, 1, MPI_INT, status.MPI_SOURCE,
WORKTAG, MPI_COMM_WORLD);
work = /* 得到下一个工作请求 */;
}
/*
* 为优异的工作请求接收结果
*/
for (rank = 1; rank < ntasks; ++rank) {
MPI_Recv(&result, 1, MPI_DOUBLE, MPI_ANY_SOURCE,
MPI_ANY_TAG, MPI_COMM_WORLD, &status);
}
/*
* 告知所有的从属进程退出
*/
for (rank = 1; rank < ntasks; ++rank) {
MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD);
}
}
slave()
{
double result;
int work;
MPI_Status status;
for ( ; ; ) {
MPI_Recv(&work, 1, MPI_INT, 0, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
/*
* 检查所接受消息的标识
*/
if (status.MPI_TAG == DIETAG) {
return;
}
result = /* 工作 */;
MPI_Send(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
}
}
MPI世界
进程由一个唯一的“标识数”(整数)表示,标识数为数0、1、2、……、N-1。MPI_COMM_WORLD指“MPI应用中的所有进程”,它称为通信子,并且提供消息传递所需的所有信息。可移植库对通信子做更多的工作,以提供大多数其它系统所不能处理的同步保护。
进入和退出MPI
与其它系统一起,提供两个函数来初始化和结束MPI进程:
MPI_Init(&argc, &argv);
MPI_Finalize( );
我是谁?他们是谁?
典型地,并行程序中的进程需要知道它是谁(它的标识数)以及其它进程是怎样存在的。一个进程通过调用MPI_Comm_rank( )来发现它自己的标识数:
int myrank;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size( )返回进程总数:
int nprocs;
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
发送消息
消息是一组给定数据类型的元素。MPI支持所有的基本数据类型,并且允许更复杂的应用程序在运行时间构造新的数据类型。
消息被发给一个指定的进程,而且用一个由用户说明的标识来标记。标识用来区分不同的由一个进程所能发送/接受的消息类型。在上面的样本代码中,标识用于区分工作和结束消息。
MPI_Send(buffer, count, datatype, destination, tag,
MPI_COMM_WORLD);
接受消息
接受进程说明标识和发送进程的标识数。MPI_ANY_TAG和MPI_ANY_SOURCE可选地用于接受任意标识和从任意发送进程而来的消息。
MPI_Recv(buffer, maxcount, datatype, source, tag,
MPI_COMM_WORLD, &status);
有关所接受消息的信息在一个状态变量中返回。所接受消息的标识是status.MPI_TAG,发送进程的标识数是status.MPI_SOURCE。
另一函数,在样本代码中没有使用,返回所接受的数据元素的个数。当所接受的元素个数小于‘最大数’时使用它。
MPI_Get_count(&status, datatype, &nelements);
通过这些函数,你会准备编写任意的应用。在MPI中有许多其它、更特异的函数,但是迄今为止所有这些函数可以在这里提到的函数上构造。
|
|