OpenMPI 学习笔记(二)执行环境

时间:2021-07-13 14:51:26
 
一、第一个例子:
OpenMPI 学习笔记(二)执行环境 // intro/minimal. #include <mpi.h>  #include <stdio.h>
int main(int argc, char** argv) {

    MPI_Init(&argc, &argv);
    printf("Sup.\n");
    MPI_Finalize();

    return 0; 
}

⚠️注意:所有使用MPI的,均需引用 <mpi.h> ,使用 MPI_Init 初始化, 通过 MPI_Finalize 关闭.


 

二、编译,执行

$ mpicc -o source source.c     //mpicc实际上只是一个对gcc的调用 (见:mpicc -showme)
 
   $ mpirun -n 2 source 
   
⚠️注意:
-n选项指定要并行运行的进程数量。如果省略-n选项,则启动的进程数取决于机器。
source是文件名,注意要写两次,第二次带.c
 

mpirun -host host0,host1 source   //允许指定执行所用的机器:这句的意思是:在host0,host1上各执行一次source。

 

我们可以结合-n和-host。如果给定的进程数是大于机器数量,我们回到第一台机器,如下:

mpirun -n 3 -host host0,host1 source
这句是指:在host0上执行一次,在host1上执行一次,然后回到host0再执行一次。

 

我们也可以使用−hostfile选项指定执行设置:

$ cat hosts

host0 slots=2  //希望host0执行2次

host1 slots=4  //希望host1执行4次   

操作如下:

mpirun -n 7 -host????file hosts source

即: 在host0上执行2次,在host1上执行一次,剩下一次回到host0执行。

man mpirun 可查看更多信息

 

三、和OpenMP比较

OpenMP的

  1. 只有一个程序实例被执行:只有一个进程。
  2. 该进程分成多个并行运行的线程。
  3. 并行部分由预处理器指令函数(#pragma)分隔

MPI

  1. 程序的多个实例同时执行:创建多个进程。
  2. 每个进程运行整个程序,并且进程并行运行。
  3. MPI_Init和MPI_Finalize不对应于并行化部分的开始和结尾。

四、默认通讯器

mpirun启动的进程必须能够相互通信。所有进程都由默认通信器链接 MPI_COMM_WORLD

MPI_COMM_WORLD 由 MPI_Init 创建并由 MPI_Finalize 销毁。每个进程都有一个在MPI_COMM_WORLD中进行标识的等级。归功于这些唯一的进程号(等级:rank)我们可以共享任务。进程之间的所有通信都通过一个通信器。

// intro/default_comm.c

#include <mpi.h> 
#include <stdio.h>

int main(int argc, char** argv) {
    MPI_Init(&argc, &argv);

    int world_size;  //总进程数
   MPI_Comm_size(MPI_COMM_WORLD, &world_size); int wrank; //进程等级号
   MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

  if (wrank!=1) //进程不为1的执行该操作 printf("Rang %d sur %d.\n", wrank, world_size); MPI_Finalize(); return 0; }

 在控制台测试:

$ mpirun -n 4 source

Rang 2 sur 4.
Rang 0 sur 4.
Rang 3 sur 4.

进程输出的顺序不固定,因为进程之间是独立的。