并行计算

MPI多级混合编程

多级混合编程概述

计算机系统的性能提升:

Scale Up(纵向扩展)模式:单个计算节点的计算能力越来越强大。

Scale Out(横向扩展)模式:可计算节点的规模越来越大。

多极化计算机的发展趋势:Scale Up + Scale Out

多级并行计算系统

架构 特点
SMP节点 节点内多个处理器彼此共享内存,节点之间通过互连网络连接,编程模型为MPI+OpenMP
多GPU 单个节点内包含多个GPU(CUDA),节点之间通过互连网络连接,编程模型为MPI+CUDA

MPI+OpenMP

MPI描述了多个进程间的并行化(独立的地址空间),通常面向分布式网络计算环境,以消息发送接收的方式进行通信。

线程并行化提供了进程内部的共享内存模式。OpenMP是一个常用的线程并行化模型,基于用户提供的编译制导语句,线程的创建和管理由编译器负责。

并行方法 优点 缺点
MPI 高可扩展性、高可移植性、节点间扩展 开发调试困难、显示通信、粗粒度划分、负载平衡困难
OpenMP 容易部署、延迟低、隐式通信、可粗细粒度划分、动态负载平 仅运行于共享内存机器、仅节点内可扩展、线程顺序未定义

MPI+OpenMP的可行性:概念上简单(两级并发),适合多核节点架构、缓解纯MPI的可扩展性问题,降低进程数和网络洪水。

单个进程内存在多个并发执行线程,所有线程共享全部的MPI对象(通信域、请求对象等),每一个线程创建多个OpenMP线程。

步骤 操作
Step1 初始化MPI
Step2 在每一个MPI进程中创建一个OpenMP并行域
Step3 在串行或并行区域调用MPI库
Step4 结束MPI

示例:

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

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

    ierr = MPI_Init(&argc, &argv[]);
    ierr = MPI_Comm_rank(..., &rank);
    ierr = MPI_Comm_rank(..., &size);

    #pragma omp parallel for
    {
        for (i=0; i<n; i++) {
            work();
        }
    }

    ierr = MPI_Finalize();
    return 0;
}

消息通信

单一线程通信:通信来自MPI并行区域的单一线程或者串行临界区。

多线程通信:通信来自MPI并行区域的多个线程。

单一线程通信 多线程通信

线程中的MPI调用

使用MPI_Init_thread选择和决定MPI线程的支持级别。

MPI_Init_thread

MPI2定义了线程调用的4种情况:

  1. Single:不支持多线程。
  2. Funneled:只有主线程能调用MPI。
  3. Serialized:多个线程可以调用MPI,但一次只允许一个线程调用。
  4. Multiple:任何线程都可以调用MPI。

MPI_THREAD_FUNNELED:需要显式调用OMP_BARRIER进行同步,此时其他线程均处在休眠状态。

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

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

    #pragma omp parallel
    {
        #pragma omp barrier
        #pragma omp master
        {
            ierr = MPI_<Whatever>(...)
        }
        #pragma omp barrier
    }
    
    return 0;
}

MPI_THREAD_SERIALIZEDOMP_BARRIER只需要在开始时候调用,此时其他线程均处于休眠状态。

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

int main(int argc, char** argv) {
    int rank, size, ierr, i;
    MPI_Init_thread(MPI_THREAD_SERIALIZED, iprovided)
    ...

    #pragma omp parallel
    {
        #pragma omp barrier
        #pragma omp master
        {
            ierr = MPI_<Whatever>(...)
        }
        // 不需要再调用 #pragma omp barrier
    }
    
    return 0;
}

MPI_THREAD_MULTIPLE:有潜在错误和死锁风险。

计算和通信重叠

某个线程负责通信,通信过程中其他线程继续执行计算。可提升效率,但同步与负载均衡更复杂。

MPI+CUDA

硬件并发:

  1. GPU层:多处理器上运行的线程。
  2. 节点层:将CPU、GPU和网卡绑定在一起。
  3. 集群层:通过互连网络将不同节点连接在一起。

并发策略:节点内采用CUDA进行并发,节点间采用MPI。

三级硬件并发

CUDA和MPI分工合作:CUDA处理GPU层次的并发,MPI负责处理节点间的并发。

可以每一个GPU由一个MPI进程负责。

数据通信

设备间的数据传输方式:

  1. Sender:将数据从设备内存拷贝到临时的host缓冲区;将host缓冲区数据进行网络发送。
  2. Receiver:接收数据时将其存入host缓冲区,将数据拷贝到设备内存。

统一寻址

在host内存和device显存之间根据访问需要自动迁移数据,同时保证二者均可访问。应用程序不需要知道访问时数据所在位置。

需要进行显式同步。

其他方法

  1. P2P:允许同一节点内部的多个GPU直接进行内存数据拷贝,不需要经过主存。
  2. RDMA:将数据从GPU直接推送到网卡,然后通过网络发送到另一台机器。
网站总访客数:Loading

使用 Hugo 构建
主题 StackJimmy 设计