MPI-note-1

MPI-note-1

Charles Lv7

MPI简述及环境配置

本系列教程参考教材——MPI并行程序设计

概述

MPI(Message Passin Interface 消息传递接口)是一种消息传递编程模型,是一个库。MPI是目前最重要的并行编程工具,它具有移植性好、功能强大、效率高等多种优点而且有多种不同的免费、高效、实用的实现版本,几乎所有的并行计算机厂商都提供对它的支持,这是其它所有的并行编程环境都无法比拟的 。

MPI是一种标准或规范的代表,并不特指某一个对它具体实现。MPI提供的调用虽然很多,但最常使用的只有6个,只要会使用 FORTRAN 77或者是C,就可以比较容易地掌握MPI的基本功能,只需通过使用这6个函数就可以完成几乎所有的通信功能。
目的:服务于进程间通信

前置知识补充

消息传输:从一个处理器的内存拷贝到另一个处理器内存的方式。
在分布式存储系统中,数据通常以消息包的形式通过网络从一个处理器发送到另一个处理器。

消息包 = 消息头控制信息 + 消息体数据信息

举例
image

序号:进程的标识,唯一
进程组:一个MPI程序的全部进程集合的一个有序子集,进程组中每个进程都被赋予了再该组中唯一的序号(rank),用于在该组中标识该进程。

环境部署

三台虚拟机均为CentOS8,一台作为控制节点,另外两台作为计算节点。

1.修改IP及主机名

1.三台主机已经修改在同一个网关
2.设置了静态ip
MPI0 192.168.10.110 控制节点
MPI1 192.168.10.111 计算节点
MPI2 192.168.10.112 计算节点
3.做好了主机名和ip地址的映射关系

2.关闭防火墙

为了mpi运行成功,尽可以能降低通信延迟和系统开销,关闭防火墙达到最高的效率

关闭firewalld

1
2
[ranan@c105 ~]$ sudo systemctl stop firewalld  //关闭防火墙
[ranan@c105 ~]$ sudo systemctl disable firewalld //设置防火墙不自启

关闭selinux
1.暂时关闭

1
setenforce 0

2.永久性关闭selinux
编辑selinux的配置文件/etc/sysconfig/selinux,把SELINUX设置成disabled,然后重启生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[ranan@c105 ~]$ sudo vim /etc/sysconfig/selinux
[ranan@c105 ~]$ cat /etc/sysconfig/selinux

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted

3.实现免密码SSH登录

hadoop免密登录的流程

4.配置MPI运行环境

三台主机都需要配置下载包

上传包到/opt/software

1
2
3
4
5
6
7
8
9
[root@c105 software]# rz
rz waiting to receive.
zmodem trl+C ȡ
正在传输 mpich-3.1.3.tar.gz...
100% 11218 KB 11218 KB/ 00:00:01 0

[root@c105 software]# ll
总用量 11220
-rw-r--r--. 1 root root 11487313 1117 16:48 mpich-3.1.3.tar.gz

解压包到/opt/module/

1
[root@c105 software]#tar -xvzf mpich-3.1.3.tar.gz -C /opt/module/

执行配置操作,作用是对即将安装的软件进行配置,检查当前的环境是否满足要安装软件的依赖关系。参数:–prefix=PREFIX 表示把所有文件装在目录PREFIX下而不是默认目录下。本系统安装目录为/home/mpi。配置成功后,最后一行提示显示“Configuration completed”。

1
[ranan@c105 mpich-3.1.3]$sudo ./configure --prefix=/home/mpi

image

报错信息:Incompatible Fortran and C Object File Types!
解决办法:sudo yum install gcc gcc-gfortran

1
2
[ranan@c105 mpich-3.1.3]$ make
[ranan@c105 mpich-3.1.3]$ make install

注意点:
step1 ./configure
step2 make
step3 make install

配置环境变量/home/mpi

1
2
3
4
5
[ranan@c105 ~]$ vim ~/.bashrc
export PATH=/home/mpi/bin:$PATH //与原来使用:进行拼接
export INCLUDE=/home/mpi/include:$INCLUDE
export LD_LIBRARY_PATH=/home/mpi/lib:$LD_LIBRARY_PATH
[ranan@c105 ~]$ source .bashrc //更新环境配置

测试是否配置成功

1
which mpicc

分发给c106 c107

5.测试

复制测试例子到/home/mpi目录下,修改/home/mpi文件权限

1
2
[root@c106 mpich-3.1.3]# cp -r examples /home/mpi
[root@c106 mpich-3.1.3]# chown -R ranan:ranan /home/mpi

单节点测试
现在是c106节点机

1
2
3
4
5
6
7
8
9
10
[ranan@c106 ~]$ cd /home/mpi/examples/
[ranan@c106 examples]$ m
Process 0 of 6 is on c106
Process 1 of 6 is on c106
Process 2 of 6 is on c106
Process 4 of 6 is on c106
Process 5 of 6 is on c106
Process 3 of 6 is on c106
pi is approximately 3.1415926544231239, Error is 0.0000000008333307
wall clock time = 0.019008

多节点测试
测试6个进程再不同权重的节点机上运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[ranan@c106 examples]$ vim nodes
[ranan@c106 examples]$ cat nodes
c105:3
c106:2
c107:1
[ranan@c106 examples]$ mpirun -np 6 -f nodes ./cpi
Process 3 of 6 is on c106
Process 0 of 6 is on c105
Process 5 of 6 is on c107
Process 4 of 6 is on c106
Process 1 of 6 is on c105
Process 2 of 6 is on c105
pi is approximately 3.1415926544231243, Error is 0.0000000008333312
wall clock time = 0.005398

程序的执行

编译语句

c
gcc编译器

1
mpicc -O2(优化选项) -o(生成可持续文件) heeloworld(编译成的执行文件名) helloworld.c(被编译的源文件)

c++
g++编译器

1
mpicxx -O2(优化选项) -o heeloworld helloworld.c

运行语句

mpi普通程序运行执行

1
mpirun(mpiexec) -np 产生的进程数 可执行文件

集群mpi上运行
集群作业调度系统特定参数 + 可执行文件

1
mpirun -np 产生的进程数 -f 集群配置文件 ./可执行文件

集群配置文件的格式

1
2
3
ip地址:进程个数
ip地址:进程个数
...

简介MPI和OPENMP

OpenMP简介

OpenMP (Open Multi-Processing) 是一个用于编程语言的并行编程的API,它支持多平台共享内存并行编程。OpenMP使用基于指令的方式来实现多线程并行。它为C, C++和Fortran提供了一套高级的并行化指令。

以下是一些OpenMP的主要特点:

  1. 基于指令:开发者只需要在代码中加入一些预处理指令,就可以指导编译器进行并行化操作。这些指令通常是以“#pragma omp”开始的。

  2. 简化的并行化:与其他并行化工具相比,OpenMP提供了一个相对简单的方法来并行化代码。开发者不需要显式地管理线程的创建和终止。

  3. 运行时库:OpenMP有一套运行时库,它提供了诸如线程管理、锁和计时等功能。

  4. 数据作用域:OpenMP提供了指令,可以明确变量在并行区域内是共享的还是私有的。

  5. 灵活的并行控制:开发者可以使用OpenMP的指令来确定并行区域,循环的并行化,任务的划分等。

  6. 可移植性:OpenMP的一个重要特点是其可移植性。相同的OpenMP代码可以在多种操作系统和硬件上运行,只要有支持OpenMP的编译器。

下面是一个使用OpenMP的简单C++代码示例,用于并行地计算数组中的元素总和:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <omp.h>

int main() {
const int N = 100000;
double a[N];
for (int i = 0; i < N; i++) {
a[i] = 1.0;
}

double sum = 0.0;

#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < N; i++) {
sum += a[i];
}

std::cout << "Sum = " << sum << std::endl;
return 0;
}

在上述代码中,#pragma omp parallel for reduction(+:sum) 指令告诉编译器并行执行for循环,并使用“reduction”来累计sum的值。

要使用OpenMP,您需要一个支持OpenMP的编译器,如GCC、Intel C++ Compiler等,并在编译时加入特定的选项,如 -fopenmp(对于GCC)。

MPI简介

MPI(Message Passing Interface)是一个用于并行计算中进程间通讯的标准和协议。与OpenMP不同,MPI适用于分布式内存系统(如计算机集群)中的并行编程,而OpenMP更适用于共享内存系统(如多核CPU)中的并行编程。MPI的目的是允许进程在独立的地址空间中运行,并通过发送和接收消息来进行通信和数据交换。

以下是一些MPI的主要特点:

  1. 分布式内存模型:MPI旨在为在不共享内存的计算机之间运行的并行进程提供通信手段。

  2. 通信原语:MPI提供了一系列函数来发送和接收消息,包括点对点通信和集合通信。

  3. 性能:MPI被设计为高效的,使其适用于高性能计算任务。

  4. 可移植性:MPI是一个标准,有多种实现(如MPICH, Open MPI等),可以在各种操作系统和硬件平台上运行。

  5. 扩展性:MPI可以在从小型多核系统到超级计算机的各种规模的系统上运行。

  6. 错误处理:MPI提供了错误检测和异常处理机制。

以下是使用MPI的简单C代码示例,展示了两个进程之间的通信:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <mpi.h>

int main(int argc, char** argv) {
int rank, size;

MPI_Init(&argc, &argv); // 初始化MPI环境
MPI_Comm_size(MPI_COMM_WORLD, &size); // 获取总进程数
MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 获取当前进程的ID

if (rank == 0) {
int data = 123;
MPI_Send(&data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); // 进程0发送数据到进程1
} else if (rank == 1) {
int recv_data;
MPI_Recv(&recv_data, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // 进程1从进程0接收数据
printf("Process 1 received data: %d\n", recv_data);
}

MPI_Finalize(); // 结束MPI环境
return 0;
}

为了编译和运行上述MPI代码,您需要一个支持MPI的编译器和库,如MPICH或Open MPI。编译后,您可以使用如mpiexecmpirun的工具来启动多个进程运行MPI程序。

MPI和OpenMP的区别与联系

MPI(Message Passing Interface)和OpenMP(Open Multi-Processing)都是并行编程的工具,但它们专为不同的并行化场景和内存模型设计。以下是MPI和OpenMP的主要区别和联系:

区别

  1. 内存模型

    • MPI:适用于分布式内存模型。在这种模型中,每个进程有其独立的内存空间,进程间的通信需要通过显式的消息传递来完成。
    • OpenMP:适用于共享内存模型。在这种模型中,所有线程共享相同的内存空间,并可以直接访问该内存。
  2. 并行实体

    • MPI:并行实体是进程。每个进程运行在其独立的地址空间中。
    • OpenMP:并行实体是线程。所有线程运行在同一个进程的地址空间中。
  3. 通信方式

    • MPI:通过发送和接收消息来进行进程间通信。
    • OpenMP:线程之间不需要显式通信,因为它们共享内存。
  4. 编程范式

    • MPI:基于消息传递的并行编程。
    • OpenMP:基于指令的并行编程。
  5. 适用场景

    • MPI:更适合大规模的并行计算任务,如在计算机集群或超级计算机上。
    • OpenMP:适用于多核或多线程的单机环境。

联系

  1. 混合并行编程:为了利用现代计算机的多级并行结构(例如,多节点的多核系统),开发者经常将MPI和OpenMP结合使用。例如,在每个节点上,可以使用MPI进行节点间的进程通信,而在节点内部,使用OpenMP进行多线程并行化。

  2. 目标:MPI和OpenMP的最终目标都是提高计算任务的性能,通过在多个计算单元上并行地执行代码来实现。

  3. 并行模式:在某些情况下,开发者可以选择使用MPI或OpenMP中的任何一种,或者两者结合,根据具体的问题和硬件架构来决定。

总的来说,MPI和OpenMP都为并行编程提供了强大的工具,但它们解决的问题和适用的场景是不同的。在实际应用中,了解它们之间的差异和如何结合使用它们可以帮助开发者更有效地并行化代码。

  • Title: MPI-note-1
  • Author: Charles
  • Created at : 2023-09-15 08:31:26
  • Updated at : 2023-09-21 11:42:05
  • Link: https://charles2530.github.io/2023/09/15/mpi-note-1/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments