入门并行编程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
未完待续~
上一篇: 104. 货仓选址——绝对值不等式的运用,中位数巧用
下一篇: 最优矩阵链乘