学习资料 《高性能计算之并行编程技术 -- MPI并行程序设计》
原理
打包(Pack)和解包(Unpack)操作是为了发送不连续的数据, 在发送前显示地把数据包装大一个连续的缓冲区, 在接收之后从连续的缓冲区中解包。
函数
MPI_PACK
MPI_PACK把由inbuf,incount, datatype指定的发送缓冲区中的incount个datatype类型的消息放到起始为 outbuf 的连续空间,该空间共有 outcount 个字节。 输入缓冲区可以是 MPI_SEND 允许的任何通信缓冲区。 入口参数 position 的值是输出缓冲区中用于打包的起始地址,打包后它的值根据打包消息的大小来增加, 出口参数 position 的值是被打包的消息占用的输出缓冲区后面的第一个地址。 通过连续几次对不同位置的消息调用打包操作, 就将不连续的消息放到了一个连续的空间。 comm参数是将在后面用于发送打包的消息时用的通信域。 (NOTE:这里要连续多次调用打包操作)
函数原型
int MPI_Pack(void* inbuf, int incount, MPI_Datatype datatype, void* outbuf, int outcount, int *position , MPI_Comm comm)
inbuf, 输入缓冲区起始地址(可选数据类型)
incount, 输入数据项个数(整型)
datatype, 每个输入数据项的类型(句柄)
outbuf, 输出缓冲区开始地址(可选数据类型)
outcount, 输出缓冲区大小(整型)
position, 缓冲区当前位置(整型)
comm,通信域
MPI_UNPACK
MPI_UNPACK 和 MPI_PACK 对应, 它从 inbuf 和 insize 指定的缓冲区空间将不连续的消息解开,放到 outbuf, outcount, datatype 指定的缓冲区中。 输出缓冲区可以是 MPI_RECV 允许的任何通信缓冲区。 输入缓冲区是一个连续的存储空间,大小为insize字节, 开始地址为 inbuf。入口参数 position的初始值是输出缓冲区中被打包消息占用的起始地址, 解包后它的值根据打包消息的大小来增加,因此出口参数 position的值是输出缓冲区中被解包的消息占用空间后面的第一个地址。 通过连续几次对已打包的消息调用与打包时相应的解包操作,就可以将连续的消息解开放到一个不连续的空间。comm参数是用于接收消息的通信域。
函数原型
int MPI_Unpack(void* inbuf, int insize, int *position, void *outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm)
inbuf, 输入缓冲区起始(可选数据类型)
insize, 输入数据项数目(整型)
position, 缓冲区当前位置,字节(整型)
outbuf, 输出缓冲区开始(可选数据类型)
outcount, 输出缓冲区大小,字节(整型)
datatype, 每个输入数据项的类型(句柄)
comm,打包的消息的通信域(句柄)
程序例子
#include <stdio.h>
#include "mpi.h"//高性能计算之并行编程技术 -- MPI并行程序设计 14.6节例子
//ROOT进程将读入一个整数和一个双精度数打包,然后广播给所有进程,各进程再将数据解包后打印int main(int argc,char **argv){
int rank;
int packsize, position;
int a;
double b;
char packbuf[100];MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);do{
if(rank==0) {
scanf("%d %lf",&a,&b);
packsize=0; /*打包开始位置*/
MPI_Pack(&a,1,MPI_INT,packbuf,100,&packsize,MPI_COMM_WORLD); /*将整数a打包*/
MPI_Pack(&b,1,MPI_DOUBLE,packbuf,100,&packsize,MPI_COMM_WORLD); /*将双精度数b打包*/
}MPI_Bcast(&packsize,1,MPI_INT,0,MPI_COMM_WORLD); /*广播打包数据的大小*/
MPI_Bcast(packbuf,packsize,MPI_PACKED,0,MPI_COMM_WORLD); /*广播打包的数据*/if(rank !=0 ){
position=0;
MPI_Unpack(packbuf,packsize,&position,&a,1,MPI_INT,MPI_COMM_WORLD); /*其他进程先将a解包*/
MPI_Unpack(packbuf,packsize,&position,&b,1,MPI_DOUBLE,MPI_COMM_WORLD); /*再将b解包*/
}
printf("Process %d got %d and %lf\n",rank,a,b);
}while(a>=0); /*若a为负数则结束,否则继续上述过程*/MPI_Finalize();
return 0;
}
浙公网安备 33010602011771号