搭建MPI并行计算环境,编写 MPI程序,求和 1 +2+3+....+1 0000。 要求:
-
1.使用100个进程;
-
2.进程0计算1 +2+...+100,
进程1计算101+ 102+...+ 200,
.....
进程99计算9901 + 9902+... +10000;
-
3.调用计时函数,分别输出每个进程的计算时间;
-
4.需使用MPI集群通信函数和同步函数
基本概念
解释的很好:MPI 与并行计算入门 - 知乎 (zhihu.com)
安装
下载:Downloads | MPICH
配置文件设置 ./configure --disable-fortran
编译安装 make -j 8; (设置8个进程进行编译会快一些)sudo make install
相关执行脚本:mpic++ mpicc mpirun mpichversion mpiexec mpicxx mpifort mpivars
确保已安装环境gcc 、cmake、gfortran,如下操作
下载mpi压缩包,解压后进行配置:
配置完后,执行编译安装
添加环境变量,注意这里的路径一定是前面配置时设置的路径,这里踩坑了
vim ~./bashrc 修改后source启用
测试安装完成
代码编写
#include <stdio.h>
#include <mpi.h>
int main(int argc, char *argv[]) {
int rank, size;
MPI_Init(&argc, &argv); // 初始化MPI环境
MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 获取进程编号
MPI_Comm_size(MPI_COMM_WORLD, &size); // 获取进程总数
if (size != 100) {
if (rank == 0) {
printf("需要100个进程,请确保启动时指定了100个进程。\n");
}
MPI_Finalize();
return 1;
}
// 每个进程计算的起点和终点
int start = rank * 100 + 1;
int end = (rank + 1) * 100;
// 计时开始
double start_time = MPI_Wtime();
// 计算部分和
long long local_sum = 0;
for (int i = start; i <= end; i++) {
local_sum += i;
}
// 计时结束
double end_time = MPI_Wtime();
double elapsed_time = end_time - start_time;
// 输出每个进程的计算时间
printf("进程 %d 计算时间: %f 秒\n", rank, elapsed_time);
// 使用MPI_Reduce收集所有部分和,结果存储在进程0
long long total_sum = 0;
MPI_Reduce(&local_sum, &total_sum, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
// 进程0输出最终总和
if (rank == 0) {
printf("1 + 2 + ... + 10000 的总和为: %lld\n", total_sum);
}
MPI_Finalize(); // 结束MPI环境
return 0;
}
代码分析
-
MPI初始化
-
MPI_Init
: 初始化MPI环境,所有进程开始运行。 -
MPI_Comm_rank
: 获取当前进程的编号(rank
)。 -
MPI_Comm_size
: 获取总进程数(size
)。
-
-
计时函数
使用MPI_Wtime()
计算每个进程的运行时间。 -
进程间通信
-
MPI_Reduce
: 将所有进程的部分和累加到进程0。 -
MPI_SUM
: 指定归约操作为求和。
-
-
同步
MPI中的MPI_Reduce
隐含了同步,因为它会等待所有进程计算完成。
运行方法
假设代码文件名为mpi_sum.c
,在终端中执行以下命令:
mpicc mpi_sum.c -o mpi_sum # 编译代码
mpirun -np 100 ./mpi_sum # 使用100个进程运行程序
运行结果