1.初探MPI——MPI简介

系列文章目录

  1. 初探MPI——MPI简介
  2. 初探MPI——(阻塞)点对点通信
  3. 初探MPI——(非阻塞)点对点通信
  4. 初探MPI——集体通信


前言

Message Passing Interface (MPI) 是一种标准化的消息传递库接口规范。该标准是消息传递模型的一种标准,该标准大量运用在科学计算领域。详尽的介绍参看MPI Tutorials


一、MPI_COMM_WORLD, size and ranks

当一个程序使用MPI运行时,所有进程都被分组到一个叫通信器(communicator)中,它们之间能相互通信。每个通信都链接到一个通信器,允许通信到达不同的进程。通信有两种类型:

  • 点对点(point to point)通信 Two processes in the same communicator are going to communicate.
  • 集体性(collective)通信All the processes in a communicator are going to communicate together.

默认通信器叫MPI_COMM_WORLD,它对程序启动时的所有进程进行分组。看下面的例子,一个程序,它运行了五个进程。每个进程都是相互连接的,并且可以在此通信器内进行通信。
在这里插入图片描述MPI_COMM_WORLD 不是 MPI 中唯一的通信者。在接下来的章节中介绍如何创建自定义通信器,但目前,让我们坚持使用 MPI_COMM_WORLD .在接下来的章节中,每次提到communicator时,只需将其替换为 MPI_COMM_WORLD .

communicator中的号码在创建后不会更改。该数字称为communicator的大小(size)。同时,communicator中的每个进程都有一个唯一的编号来识别它。此数字称为进程的秩(rank)。在前面的示例中,MPI_COMM_WORLD 的size为 5。每个进程的rank是每个圆圈内的数字。进程的秩始终在 0 到 size - 1 之间 。

二、Hello World

编写一个跨多个进程的简单Hello World代码

首先,MPI必须初始化(initialised)和结束(finalised)。**这两个操作必须始终是代码的第一次和最后一次调用。**现在关于这两个操作没有太多可说的,我们只是说他们是程序的setup。
MPICH 实现文档,它警告我们:

The MPI standard does not say what a program can do before an MPI_INIT or after an MPI_FINALIZE. 
In the MPICH implementation, you should do as little as possible. 
In particular, avoid anything that changes the external state of 
the program, such as opening files, reading standard input or writing to standard output.

因此,按照惯例,这两个命令在程序中始终被调用为第一个和最后一个。对应的命令是 MPI_InitMPI_Finalize MPI_Init 总是引用命令行参数,而 MPI_Finalize 不接受。因此,在 C++ 中,它们的签名如下:

int MPI_Init(int *argc, char ***argv);
int MPI_Finalize();

获得rank和size的方法,遵循以下调用:

int size, rank;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

请注意 MPI_COMM_WORLD . MPI_COMM_WORLD 这表明该操作是在封装了当前运行的每个进程的全局通信器上完成的。我们稍后将看到什么是通信器以及如何创建它们以创建流程组。目前,我们将坚持在本章的 WORLD 通信器上调用 MPI。

Instructions

  • Initialises MPI.
  • Reads the rank of the current process on MPI_COMM_WORLD.
  • Prints Hello world, from process #<RANK OF THE PROCESS.
  • Finalizes MPI and exits.
#include <iostream>
#include <mpi.h>

int main(int argc, char** argv) {
  // Initialisation
  MPI_Init(&argc, &argv);
  // Reading size and rank
  int world_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
  // Printing
  std::cout << "Hello world, from process #" << world_rank << std::endl;
  
  // Finalisation
  MPI_Finalize();

  return 0;
}

运行结果:
在这里插入图片描述在本地机器上运行需要注意,有一种简单的方法可以编译 MPI 代码。安装任何实现(如 OpenMPI 或 MPICH)时,都会提供wrapper compilers。如果要在安装 OpenMPI 发行版后编译此代码,则必须替换简单的编译器行:

g++ -o hello_world hello_world.cpp  
替换为下面编译指令
mpicxx -o hello_world hello_world.cpp

有三种这样的包装器可以用 MPI 实现主要支持的三种语言进行编译:C、C++ 和 Fortran。相应的包装器是 : mpicc 和 mpicxx mpifort 。请注意,这些命令只是包装器,它们将使用环境变量调用编译器。通过 --show 使用命令行参数,可以看到使用这些编译器之一时实际执行的行。例如,在相当标准的 Linux 安装中, mpicxx --show 将返回如下内容:

g++ -I/usr/local/include -pthread -Wl,-rpath -Wl,/usr/local/lib -Wl,--enable-new-dtags -L/usr/local/lib -lmpi_cxx -lmpi

编译程序后,可以使用该 mpirun 命令跨多个进程运行该程序

mpirun -np 4 ./hello_world

总结

  1. MPI简介,消息传递模型
  2. global communicator
  3. rank 和 size
  4. 初始化和结束
  5. 使用MPI进行简单的hello world小程序编写

参考

  1. Introduction to MPI
  2. MPI Tutorials
  • 27
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值