MPI编程汇总各进程均值求总均值(禁用MPI_Reduce)及代码排错
问题分析
你的代码存在几个关键错误,直接导致了异常输出:
- 输入顺序错误:根进程在读取
m之前就计算size*m,此时m未初始化,值为随机垃圾值(大概率是0),所以会打印Enter 0 elements,后续输入逻辑完全混乱。 - 总均值计算逻辑错误:根进程通过
MPI_Gather收集到了size个进程的均值,但你用for (int i = 0; i < m; i++)循环累加,循环次数完全错误,应该遍历size次;同时累加前未重置avg,会把根进程自身的均值重复计算。 - 固定数组大小限制:
arr[10]和ans[10]的固定大小会导致当size*m超过10时数组越界,引发未知错误。 - 变量初始化不严谨:非根进程的
sum和avg未显式初始化,可能被垃圾值干扰计算。
修复后的代码
#include<stdio.h> #include<stdlib.h> #include<mpi.h> int main(int argc, char *argv[]){ int rank, size, m; int *arr = NULL; int *ans = NULL; float avg = 0.0f, sum = 0.0f; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0){ fprintf(stdout, "Enter m:\n"); fflush(stdout); // 先读取m的值,再计算需要输入的元素总数 scanf("%d", &m); fprintf(stdout, "Enter %d elements:\n", size * m); fflush(stdout); // 动态分配数组,适配任意合法的size和m arr = (int*)malloc(size * m * sizeof(int)); for (int i = 0; i < size * m; i++){ scanf("%d", &arr[i]); } } // 广播m到所有进程,确保非根进程知道要处理的元素数量 MPI_Bcast(&m, 1, MPI_INT, 0, MPI_COMM_WORLD); // 非根进程分配接收数据的内存 if (rank != 0){ ans = (int*)malloc(m * sizeof(int)); } // 分发数据到各个进程 MPI_Scatter(arr, m, MPI_INT, ans, m, MPI_INT, 0, MPI_COMM_WORLD); // 计算当前进程的局部均值 sum = 0.0f; for (int i = 0; i < m; i++){ sum += ans[i]; } avg = sum / m; // 根进程分配存储所有进程均值的内存 float *all_avgs = NULL; if (rank == 0){ all_avgs = (float*)malloc(size * sizeof(float)); } // 收集所有进程的均值到根进程 MPI_Gather(&avg, 1, MPI_FLOAT, all_avgs, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); if (rank == 0){ // 重新初始化变量计算总均值,避免和局部均值混淆 float total_avg = 0.0f; // 遍历所有进程的均值,共size个 for (int i = 0; i < size; i++){ total_avg += all_avgs[i]; } total_avg /= size; fprintf(stdout, "The average of all values: %f\n", total_avg); fflush(stdout); // 释放动态分配的内存 free(arr); free(all_avgs); } else { free(ans); } MPI_Finalize(); return 0; }
修复要点说明
- 调整输入流程:根进程先读取
m,再计算需要输入的元素总数,确保m已被正确赋值。 - 修正总均值计算:根进程循环
size次累加所有进程的均值,使用独立变量total_avg避免和局部均值混淆。 - 动态内存分配:替换固定大小数组为动态分配,适配任意合法的进程数和元素数量,避免数组越界。
- 严谨的变量初始化:显式初始化
sum和avg,避免垃圾值干扰计算。 - 内存释放:所有动态分配的内存使用后及时释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者dev0419
相关产品推荐
相关产品推荐

