欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

入门并行编程MPI(二)

程序员文章站 2022-07-12 21:35:08
...

MPI数据类型

  • 消息中的数据由一个三联体描述:(地址,计数,数据类型),其中数据类型被递归定义为:
  •         与基础语言中的数据类型相对应的预定义基础类型(例如MPI_INT,MPI_DOUBLE_PRECISION)。
  •         MPI类型的连续阵列
  •         矢量类型
  •         索引类型
  •         任意的结构
  • MPI包括建立自定义数据类型的函数,例如,描述对(int, float)的数据类型。

基本数据类型

MPI datatype

C datatype

MPI_CHAR

signed char

MPI_SHORT

signed short int

MPI_INT

signed int

MPI_LONG

signed long int

MPI_UNSIGNED_CHAR

unsigned char

MPI_UNSIGNED_SHORT

unsigned short int

MPI_UNSIGNED

unsigned int

MPI_UNSIGNED_LONG

unsigned long int

MPI_FLOAT

float

MPI_DOUBLE

double

MPI_LONG_DOUBLE

long double

标签的概念

  • 一条信息伴随着一个用户定义的属性,以识别正在接收的信息。
  • 发送方和接收方的信息标签必须是一致的。
  • 可以指定一个MPI_ANY_TAG常量作为标签值。
  • 一些非MPI消息传递系统将标记称为消息类型。
  • MPI引入了标签的概念,以避免与MPI数据类型相混淆。

MPI函数格式

error = MPI_Xxxxx(parameter,...);
   MPI_Xxxxx(parameter,...);

返回值是错误代码。由MPI_SUCCESS常数定义

	int error;
	......
	error = MPI_Init(&argc, &argv));
	if (error != MPI_SUCCESS)
	{
		fprintf (stderr, “ MPI_Init error \n”);	
		return 1; 

	}

运行一个MPI程序

在启动时,指定所需的处理器数量np和程序的名称 
    mpirun –np 3 prog

在选定的计算节点上运行指定程序的np拷贝。

 每个程序副本得到两个值。
         np
         rank的范围[0 ... np-1]

任何两个程序都可以使用消息传递函数直接交换数据

C: MPI helloworld.c

#include <mpi.h>
main(int argc, char **argv)
{
	int numtasks, rank;
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, & numtasks);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	printf("Hello World from process %d of %d\n“, rank, numtasks);
	MPI_Finalize();
}

环境定义函数

int MPI_Init(int *argc, char ***argv)
	应该是第一个调用,只调用一次

int MPI_Comm_size(MPI_Comm comm, int *size)
   通讯器中的进程数

int MPI_Comm_rank(MPI_Comm comm, int *rank)
   通讯器中的进程编号(从0开始编号)

int MPI_Finalize()
   完成进程的操作

int MPI_Abort (MPI_Comm comm, int*errorcode)
	终止程序

int MPI_Initialized(int *flag)
如果在MPI_Init过程之后调用,flag参数返回1,否则返回0

int MPI_Finalized(int *flag)
如果在 MPI_Finalize ,否则为0
这些程序可以在MPI_Init之前和MPI_Finalize之后调用

int MPI_Get_processor_name(char *name, int *len)
在名称字符串中返回调用进程所运行的节点的名称。变量len返回名称中的字符数,不超过MPI_MAX_PROCESSOR_NAME常数

计时器操作函数

double MPI_Wtime(void)
	为每个被触发的进程返回自过去某个时间点以来所经过的天文时间,单位为秒(双精度实数)。用作参考点的时间时刻在过程的有效期内不会改变

double MPI_Wtick(void)
	返回定时器的分辨率,单位是秒

使用定时器

#include <stdio.h>
#include "mpi.h"
#define NTIMES 1000
int main(int argc, char **argv)
{
   double time_start, time_finish, tick;
   int rank, i;
   int len;
   char *name;
   name = (char*)malloc(MPI_MAX_PROCESSOR_NAME*sizeof(char));
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Get_processor_name(name, &len);
   tick = MPI_Wtick();
   time_start = MPI_Wtime();
   for (i = 0; i<NTIMES; i++)time_finish = MPI_Wtime();
   printf ("node %s, process %d: tick= %lf, time= %lf\n",
        name, rank, tick, (time_finish-time_start)/NTIMES);
   MPI_Finalize();
}


报文状态信息

包含:
源: status.MPI_SOURCE
标签: status.MPI_TAG
错误代码:status.MPI_ERROR
计数:MPI_Get_count


未完待续~