开发者
资源
鲲鹏HyperMPI高性能通信:编译安装与性能测试实战
鲲鹏HyperMPI高性能通信:编译安装与性能测试实战
原创
发表于05/08
1.6k0

一、HyperMPI是什么

HyperMPI(HMPI)是华为基于Open MPI开发的高性能通信库,专门为鲲鹏平台优化了集合通信操作。在HPC(高性能计算)场景中,多个计算节点之间的数据交换效率直接决定了整体计算速度,而集合通信(广播、规约、同步等)是最核心的通信模式。

标准Open MPI的集合通信采用P2P(点对点)方式实现,通信效率有瓶颈。HyperMPI在UCX框架基础上新增了UCG集合通信模块,南向直接对接传输层,绕过了协议层的开销,配合华为自研的集合通信算法,在大规模并行计算场景下性能提升明显。

本文在华为云开发者空间(鲲鹏aarch64,4VCPUs 8GiB)环境下,实操HyperMPI的编译安装和基础性能测试。

二、HyperMPI架构理解

在动手安装之前,先理解HyperMPI的软件分层:

┌──────────────────────────────────┐
│         HyperMPI层                │
│   ┌──────────┐  ┌──────────┐    │
│   │   P2P    │  │  COLL    │    │  ← MPI接口层
│   │(点对点)  │  │(集合操作) │    │
│   └────┬─────┘  └────┬─────┘    │
├───────┼──────────────┼──────────┤
│         HUCX层                    │
│   ┌───┴───┐ ┌─────┴──┐ ┌────┐  │
│   │  UCP  │ │  UCG   │ │ UCT│  │  ← 通信框架层
│   │(协议) │ │(集合通信)│ │(传输)│ │
│   └───────┘ └────────┘ └────┘  │
└──────────────────────────────────┘

关键模块说明:

UCG:华为新增的集合通信模块,这是HyperMPI相对Open MPI的核心差异

COLL:华为自研的集合操作组件,调用UCG实现高性能集合通信

HUCX:华为优化的UCX通信框架,提供底层传输支持

HyperMPI支持三种优化的集合通信操作:MPI_Allreduce(全规约)、MPI_Bcast(广播)、MPI_Barrier(同步),这三种操作覆盖了HPC场景中80%以上的通信需求。

三、编译安装

HyperMPI的安装分三步:先编译HUCX,再编译XUCG(集合通信模块),最后编译HyperMPI。三者的编译顺序不能调换。

3.1 安装依赖

# 安装编译依赖
sudo dnf install -y gcc gcc-c++ make autoconf automake libtool \
  perl-Data-Dumper numactl-devel binutils flex systemd-devel \
  valgrind cmake

# 检查GCC版本(openEuler 22.03默认GCC 10.x,满足9.3.0以上的要求)
gcc -v
# 输出应包含:GCC version 10.x.x

# 安装environment-modules(后续加载HMPI环境需要)
sudo dnf install -y environment-modules
source /usr/share/Modules/init/bash

3.2 编译HUCX

# 创建安装目录
sudo mkdir -p /opt/hmpi-install/hucx /opt/hmpi-install/xucg /opt/hmpi-install/hmpi
# 将安装目录的所有权改为当前用户(避免make install时权限问题)
sudo chown -R $(whoami) /opt/hmpi-install

# 下载HUCX源码包
cd /tmp
wget https://gitee.com/kunpengcompute/hucx/archive/refs/tags/v1.3.0.spc002-huawei.tar.gz

# 解压并编译
tar -zxvf v1.3.0.spc002-huawei.tar.gz
cd hucx-v1.3.0.spc002-huawei/

./autogen.sh

# 配置编译,--enable-mt启用多线程支持
./contrib/configure-opt --prefix=/opt/hmpi-install/hucx --enable-mt

# 编译安装(4核环境用-j4,根据实际核数调整)
make -j4
make -j4 install
```

**编译时间约10-15分钟。如果编译报错提示缺少numactl,追加 **`--disable-numa` 参数重新configure。

### 3.3 编译XUCG

**XUCG是UCG集合通信模块的源码,需要用cmake独立编译:**

```
# 下载XUCG源码包
cd /tmp
wget https://gitee.com/kunpengcompute/xucg/archive/refs/tags/v1.3.0.spc001-huawei.tar.gz

# 解压
tar -zxvf v1.3.0.spc001-huawei.tar.gz
cd xucg-v1.3.0.spc001-huawei/

# 创建编译目录
mkdir build && cd build

# cmake配置(指定HUCX安装路径和安装目录)
cmake .. \
  -DCMAKE_INSTALL_PREFIX=/opt/hmpi-install/xucg \
  -DCMAKE_BUILD_TYPE=Release \
  -DUCG_BUILD_WITH_UCX=/opt/hmpi-install/hucx \
  -DUCG_ENABLE_MT=ON \
  -DUCG_BUILD_TESTS=OFF

# 编译安装
make -j4
make -j4 install
```

### 3.4 编译HyperMPI

**编译HMPI之前,需要先加载HUCX和XUCG的环境变量:**

```
# 加载HUCX和XUCG环境变量(HMPI的configure需要找到它们)
export LD_LIBRARY_PATH=/opt/hmpi-install/hucx/lib:/opt/hmpi-install/xucg/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=/opt/hmpi-install/hucx/include:/opt/hmpi-install/xucg/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=/opt/hmpi-install/hucx/include:/opt/hmpi-install/xucg/include:$CPLUS_INCLUDE_PATH

# 下载HMPI源码包
cd /tmp
wget https://gitee.com/kunpengcompute/hmpi/archive/refs/tags/v1.3.0.spc001-huawei.tar.gz

# 解压并编译
tar -zxvf v1.3.0.spc001-huawei.tar.gz
cd hmpi-v1.3.0.spc001-huawei/

./autogen.pl

# 配置编译,同时指定HUCX和XUCG的安装路径
./configure --prefix=/opt/hmpi-install/hmpi \
  --with-platform=contrib/platform/mellanox/optimized \
  --enable-mpi1-compatibility \
  --with-ucx=/opt/hmpi-install/hucx \
  --with-ucg=/opt/hmpi-install/xucg

# 注意:HMPI不能使用make -j并行编译,必须单线程make
make
make install

**编译时间较长(约20-30分钟),HMPI的Makefile不支持并行编译,使用 **make -j 可能导致构建失败,必须用单线程 make

3.5 配置环境变量

# 创建module配置文件(包含hmpi、hucx、xucg三个路径)
cat > /opt/hmpi-install/Hmpi_modulefiles << 'EOF'
#%Module1.0
conflict mpi
prepend-path  OPAL_PREFIX /opt/hmpi-install/hmpi/
prepend-path  PATH /opt/hmpi-install/hmpi/bin:/opt/hmpi-install/hucx/bin:/opt/hmpi-install/xucg/bin
prepend-path  LD_LIBRARY_PATH /opt/hmpi-install/hmpi/lib:/opt/hmpi-install/hucx/lib:/opt/hmpi-install/xucg/lib
prepend-path  INCLUDE /opt/hmpi-install/hmpi/include:/opt/hmpi-install/hucx/include:/opt/hmpi-install/xucg/include
EOF

# 加载环境
module use /opt/hmpi-install
module load /opt/hmpi-install/Hmpi_modulefiles

# 写入bashrc持久化
echo 'module use /opt/hmpi-install' >> ~/.bashrc
echo 'module load /opt/hmpi-install/Hmpi_modulefiles' >> ~/.bashrc

# 验证安装
mpirun --version
# 输出应包含:mpirun (Open MPI) 4.1.1

四、编写MPI测试程序

4.1 基础点对点通信测试

创建一个简单的MPI程序,测试两个进程之间的数据传递:

# 创建测试程序
cat > hello_mpi.c << 'EOF'
#include <mpi.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    int rank, size;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    printf("Process %d/%d: MPI OK\n", rank, size);

    MPI_Finalize();
    return 0;
}
EOF

# 使用HyperMPI的mpicc编译
mpicc -o hello_mpi hello_mpi.c

# 在本地启动4个进程
mpirun -np 4 ./hello_mpi

# 输出:
# Process 0/4: MPI OK
# Process 1/4: MPI OK
# Process 2/4: MPI OK
# Process 3/4: MPI OK

4.2 集合通信性能测试

创建一个测试MPI_Allreduce性能的程序:

# 创建性能测试程序
cat > allreduce_bench.c << 'EOF'
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 1000000
#define ITERATIONS 100

int main(int argc, char *argv[]) {
    int rank, size;
    double *buffer = NULL;
    double start_time, end_time;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    /* 使用malloc分配大数组,避免栈溢出 */
    buffer = (double *)malloc(ARRAY_SIZE * sizeof(double));
    if (buffer == NULL) {
        fprintf(stderr, "malloc failed\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

    /* 初始化数据 */
    for (int i = 0; i < ARRAY_SIZE; i++) {
        buffer[i] = (double)rank + i * 0.001;
    }

    /* 预热 */
    MPI_Allreduce(MPI_IN_PLACE, buffer, ARRAY_SIZE, MPI_DOUBLE,
                  MPI_SUM, MPI_COMM_WORLD);

    /* 正式测试 */
    start_time = MPI_Wtime();
    for (int i = 0; i < ITERATIONS; i++) {
        MPI_Allreduce(MPI_IN_PLACE, buffer, ARRAY_SIZE, MPI_DOUBLE,
                      MPI_SUM, MPI_COMM_WORLD);
    }
    end_time = MPI_Wtime();

    if (rank == 0) {
        double avg_time = (end_time - start_time) / ITERATIONS * 1000;
        double data_size = ARRAY_SIZE * sizeof(double) / 1024.0 / 1024.0;
        printf("MPI_Allreduce benchmark:\n");
        printf("  Data size: %.2f MB\n", data_size);
        printf("  Processes: %d\n", size);
        printf("  Avg time:  %.3f ms/op\n", avg_time);
        printf("  Bandwidth: %.2f MB/s\n", data_size / (avg_time / 1000.0));
    }

    free(buffer);
    MPI_Finalize();
    return 0;
}
EOF

# 编译
mpicc -O2 -o allreduce_bench allreduce_bench.c

# 4进程测试
mpirun -np 4 ./allreduce_bench

# 输出示例:
# MPI_Allreduce benchmark:
#   Data size: 7.63 MB
#   Processes: 4
#   Avg time:  2.156 ms/op
#   Bandwidth: 3539.51 MB/s

五、HyperMPI vs Open MPI性能对比

在相同环境下,对比HyperMPI和标准Open MPI的集合通信性能:

# 安装标准Open MPI(openEuler 22.03仓库自带)
# openmpi包只包含运行时,openmpi-devel包含编译器mpicc
sudo dnf install -y openmpi openmpi-devel

# 切换到Open MPI环境(openEuler的openmpi未配置module,需手动设置PATH)
module unload /opt/hmpi-install/Hmpi_modulefiles
export PATH=/usr/lib64/openmpi/bin:$PATH
export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib:$LD_LIBRARY_PATH

# 确认使用的是Open MPI的mpicc
which mpicc
# 输出应为:/usr/lib64/openmpi/bin/mpicc

# 用Open MPI编译并运行同样的测试
mpicc -O2 -o allreduce_bench_ompi allreduce_bench.c
mpirun -np 4 ./allreduce_bench_ompi

测试完成后切换回HyperMPI:

# 清除Open MPI环境变量
export PATH=$(echo $PATH | sed 's|/usr/lib64/openmpi/bin:||')
export LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | sed 's|/usr/lib64/openmpi/lib:||')

# 加载HyperMPI环境
module load /opt/hmpi-install/Hmpi_modulefiles

在鲲鹏920 4核环境下的典型对比结果:

操作数据量Open MPI耗时HyperMPI耗时提升比例
MPI_Allreduce8MB3.8ms2.2ms1.7x
MPI_Bcast8MB2.1ms1.3ms1.6x
MPI_Barrier-0.15ms0.08ms1.9x

注意:单机4核环境下的提升幅度有限(HyperMPI的优势在大规模集群场景更明显),但已经能看出UCG模块的效果。以上数据为典型参考值,实际结果受硬件配置和网络环境影响。

六、收获与反思

编译顺序严格:HUCX → XUCG → HMPI。三者有层层依赖关系,XUCG依赖HUCX,HMPI依赖HUCX和XUCG。顺序搞反了,configure阶段就会报错找不到依赖。

XUCG用cmake独立编译。和早期版本(v1.2.x)不同,v1.3.0版本的XUCG不再复制到HUCX目录,而是用cmake独立编译安装,HMPI编译时通过 --with-ucg 指定XUCG路径。

HMPI不能并行编译。HUCX和XUCG可以用 make -j4 加速,但HMPI的Makefile有依赖顺序问题,必须单线程 make,否则会随机失败。

单机测试只是起点。HyperMPI的真正价值在多节点集群场景。单机上,UCG的集合通信优化和P2P差异不大。但如果有多台鲲鹏服务器通过InfiniBand或RoCE网络互联,HyperMPI的UCG模块优势会非常明显。

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞