一、实验环境搭建
本次MPI集群环境是在电脑中安装mpi的sdk和应用程序后在visual studio 2022 上配置MPI环境。
- VC++目录---》包含目录---》添加MPI的include目录
- VC++目录---》库目录---》添加MPI的x64目录
- VC++目录---》预编译器---》输入"MPICH_SKIP_MPICXX"点击确认。
- VC++目录---》代码生成---》运行库选择"多线程调试(/MTd)"。
- 链接器---》输入---》x64里面三个文件的名字。
- 完成以上配置之后就点击生成解决方案即可。
二、MPI程序代码
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>`
// 计算从start到end的和
long long sum(int start, int end) {
long long result = 0;
for (int i = start; i <= end; ++i) {
result += i;
}
return result;
}
int main(int argc, char* argv[]) {
int rank, size;
long long total_sum = 0;
int start, end;
double start_time, end_time;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); //通信域,一般为 MPI_COMM_WORLD返回执行当前代码的进程号rank
MPI_Comm_size(MPI_COMM_WORLD, &size); //通信域,一般为 MPI_COMM_WORLD返回进程总数size
// 计算每个进程的工作范围
int total_numbers = 10000;
int chunk_size = total_numbers / size; //分支大小
int remainder = total_numbers % size;
if (rank < remainder) {
// 前remainder个进程多处理一个数
start = rank * (chunk_size + 1) + 1;
end = start + chunk_size;
}
else {
// 其余进程
start = rank * chunk_size + remainder + 1;
end = start + chunk_size - 1;
}
// 开始计时
start_time = MPI_Wtime();
// 计算部分和
long long partial_sum = sum(start, end);
// 结束计时
end_time = MPI_Wtime();
//在指定的通信器中执行屏障同步,确保所有进程在此点上同步,直到所有进程都到达屏障。
MPI_Barrier(MPI_COMM_WORLD);
// 输出每个进程的计算时间和范围
printf("Process %d computed sum from %d to %d in %.6f seconds\n", rank, start, end, end_time - start_time);
//函数 MPI_Reduce(),将通信子内各进程的同一个变量参与规约计算,并向指定的进程输出计算结果
// 将部分和汇总到进程0
MPI_Reduce(&partial_sum, &total_sum, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
// 进程0输出总和
if (rank == 0) {
printf("Total sum from 1 to %d is %lld\n", total_numbers, total_sum);
printf("Number of processes used: %d\n", size);
}
MPI_Finalize();
return 0;
}
集群通信函数:使用MPI_Reduce()函数将每个进程的局部和汇总到进程rank0。
同步函数:使用MPI_Barrier()同步函数,确保所有进程在同一个时间点停留,直到所有进程都到达该点。可以用来确保所有进程在继续执行之前都完成了某个阶段的工作。
时间函数:使用MPI_Wtime()函数,返回一个高精度的时间戳,测量出每个进程的时间间隔。
三、运行结果截图及分析
1.实验结果显示1+2+......10000=50005000,即计算的结果正确。
2.使用MPI_Barrir()函数保证了所有进程在被调用之后才执行,保证了通信进程的同步。
3.MPI通过优化消息传递机制,实现了节点间的高效通信,从而显著提升了并行计算的效率。