news 2026/2/16 19:06:12

MPI 广播一个数组代码示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MPI 广播一个数组代码示例

1.基本广播操作 (MPI_Bcast)

#include <stdio.h> #include <stdlib.h> #include <mpi.h> int main(int argc, char** argv) { MPI_Init(&argc, &argv); int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int n = 10; // 数组长度 int* array = NULL; // 根进程(通常是 rank 0)初始化数组 if (rank == 0) { array = (int*)malloc(n * sizeof(int)); for (int i = 0; i < n; i++) { array[i] = i * 10; // 示例数据 } printf("Rank %d: Initialized array: ", rank); for (int i = 0; i < n; i++) { printf("%d ", array[i]); } printf("\n"); } else { // 其他进程分配内存 array = (int*)malloc(n * sizeof(int)); } // 广播数组长度(先广播长度,再广播数据) MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); // 广播整个数组 MPI_Bcast(array, n, MPI_INT, 0, MPI_COMM_WORLD); // 所有进程打印接收到的数组 printf("Rank %d: Received array: ", rank); for (int i = 0; i < n; i++) { printf("%d ", array[i]); } printf("\n"); free(array); MPI_Finalize(); return 0; }

2.动态数组广播(长度未知)

#include <stdio.h> #include <stdlib.h> #include <mpi.h> int main(int argc, char** argv) { MPI_Init(&argc, &argv); int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int* array = NULL; int n = 0; // 根进程确定数组长度和内容 if (rank == 0) { // 假设根据某些条件确定长度 n = size * 3; // 示例:每个进程处理3个元素 array = (int*)malloc(n * sizeof(int)); for (int i = 0; i < n; i++) { array[i] = i * 5; } printf("Root: Broadcasting array of size %d\n", n); } // 第一步:广播数组长度 MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); // 非根进程分配内存 if (rank != 0) { array = (int*)malloc(n * sizeof(int)); } // 第二步:广播数组数据 MPI_Bcast(array, n, MPI_INT, 0, MPI_COMM_WORLD); // 验证广播结果 printf("Rank %d: First element = %d, Last element = %d\n", rank, array[0], array[n-1]); free(array); MPI_Finalize(); return 0; }

3.二维数组广播

#include <stdio.h> #include <stdlib.h> #include <mpi.h> int main(int argc, char** argv) { MPI_Init(&argc, &argv); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int rows = 3, cols = 4; int** matrix = NULL; // 根进程初始化矩阵 if (rank == 0) { matrix = (int**)malloc(rows * sizeof(int*)); for (int i = 0; i < rows; i++) { matrix[i] = (int*)malloc(cols * sizeof(int)); for (int j = 0; j < cols; j++) { matrix[i][j] = i * cols + j; } } printf("Root matrix:\n"); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%2d ", matrix[i][j]); } printf("\n"); } } // 广播维度信息 int dims[2]; if (rank == 0) { dims[0] = rows; dims[1] = cols; } MPI_Bcast(dims, 2, MPI_INT, 0, MPI_COMM_WORLD); rows = dims[0]; cols = dims[1]; // 非根进程分配内存 if (rank != 0) { matrix = (int**)malloc(rows * sizeof(int*)); for (int i = 0; i < rows; i++) { matrix[i] = (int*)malloc(cols * sizeof(int)); } } // 逐行广播(二维数组在内存中不连续) for (int i = 0; i < rows; i++) { MPI_Bcast(matrix[i], cols, MPI_INT, 0, MPI_COMM_WORLD); } // 验证结果 printf("Rank %d: matrix[1][2] = %d\n", rank, matrix[1][2]); // 清理内存 for (int i = 0; i < rows; i++) { free(matrix[i]); } free(matrix); MPI_Finalize(); return 0; }

4.使用派生数据类型广播连续内存块

#include <stdio.h> #include <stdlib.h> #include <mpi.h> typedef struct { int id; double value; char name[20]; } Data; int main(int argc, char** argv) { MPI_Init(&argc, &argv); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int count = 5; Data* data_array = NULL; // 创建派生数据类型 MPI_Datatype MPI_DATA_TYPE; int blocklengths[3] = {1, 1, 20}; MPI_Aint displacements[3]; MPI_Datatype types[3] = {MPI_INT, MPI_DOUBLE, MPI_CHAR}; Data dummy; MPI_Get_address(&dummy.id, &displacements[0]); MPI_Get_address(&dummy.value, &displacements[1]); MPI_Get_address(&dummy.name, &displacements[2]); // 计算相对位移 for (int i = 2; i >= 0; i--) { displacements[i] -= displacements[0]; } MPI_Type_create_struct(3, blocklengths, displacements, types, &MPI_DATA_TYPE); MPI_Type_commit(&MPI_DATA_TYPE); // 根进程初始化数据 if (rank == 0) { data_array = (Data*)malloc(count * sizeof(Data)); for (int i = 0; i < count; i++) { data_array[i].id = i; data_array[i].value = i * 1.5; sprintf(data_array[i].name, "Item_%d", i); } } else { data_array = (Data*)malloc(count * sizeof(Data)); } // 广播数据 MPI_Bcast(data_array, count, MPI_DATA_TYPE, 0, MPI_COMM_WORLD); // 验证结果 printf("Rank %d: Data[2] = {id:%d, value:%.2f, name:%s}\n", rank, data_array[2].id, data_array[2].value, data_array[2].name); free(data_array); MPI_Type_free(&MPI_DATA_TYPE); MPI_Finalize(); return 0; }

5.编译和运行

# 编译 mpicc -o broadcast_array broadcast_array.c # 运行(使用4个进程) mpirun -np 4 ./broadcast_array # 或指定机器文件 mpirun -np 4 -machinefile hosts.txt ./broadcast_array

6.MPI 广播的知识点总结

  1. MPI_Bcast 参数

    int MPI_Bcast(void *buffer, // 数据缓冲区 int count, // 元素数量 MPI_Datatype datatype, // 数据类型 int root, // 根进程rank MPI_Comm comm) // 通信域
  2. 广播步骤

    • 根进程准备数据

    • 非根进程分配内存

    • 广播长度信息(如果需要)

    • 广播数据本身

  3. 内存管理

    • 所有进程都需要为接收的数据分配内存

    • 广播前内存必须已分配

    • 广播后所有进程的数据完全相同

  4. 性能考虑

    • 大数组广播可能成为性能瓶颈

    • 考虑使用 scatter/gather 或特定模式

    • 对于非常大的数据,可能需要分段广播

  5. 错误处理

    • 检查内存分配是否成功

    • 验证广播返回值

    • 确保所有进程使用相同的参数

这个示例展示了 MPI 中广播数组的基本用法,可以根据实际需求进行调整和优化。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/16 14:13:44

基于SpringCloud的分布式演唱会抢票系统(源码+lw+部署文档+讲解等)

课题介绍本课题旨在设计并实现一套基于SpringCloud的分布式演唱会抢票系统&#xff0c;解决传统抢票系统并发量不足、抢票卡顿、数据不一致、票务管控混乱及分布式部署困难等问题&#xff0c;适配演唱会抢票高并发、高可用、数据实时同步的核心需求。系统采用SpringCloud分布式…

作者头像 李华
网站建设 2026/2/16 16:46:19

基于大数据的老旧小区改造需求评估与分析系统(源码+lw+部署文档+讲解等)

课题介绍 本课题旨在设计并实现一套基于大数据的老旧小区改造需求评估与分析系统&#xff0c;解决当前老旧小区改造中需求收集零散、评估标准不统一、数据分析滞后、改造方案针对性不足等问题&#xff0c;适配社区、住建部门对老旧小区改造的科学化、精准化管控需求。系统融合大…

作者头像 李华
网站建设 2026/2/12 11:28:48

[深度强化学习算法进阶项目】[源代码+论文】(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

分层多智能体强化学习及自对弈训练—轻量化空战机动系统的深度 [深度强化学习算法进阶项目】[源代码论文】(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码基于一种分层多智能体强化学习框架&#xff0c; 通过高层指挥官策略与…

作者头像 李华
网站建设 2026/2/13 5:19:56

基于SpringBoot和Vue的共享单车管理系统(源码+lw+部署文档+讲解等)

课题介绍 本课题旨在设计并实现一套基于SpringBoot和Vue的共享单车管理系统&#xff0c;解决当前共享单车运营中车辆调度不便、故障上报不及时、用户骑行记录混乱、运维效率偏低等问题&#xff0c;适配城市共享单车规范化运营与信息化管理的核心需求。系统采用前后端分离架构&a…

作者头像 李华
网站建设 2026/2/14 18:03:45

基于SpringBoot的智能阅读推荐系统(源码+lw+部署文档+讲解等)

课题介绍 本课题旨在设计并实现一套基于SpringBoot的智能阅读推荐系统&#xff0c;解决当前阅读平台内容杂乱、用户找书低效、推荐精准度不足、阅读偏好匹配度低等问题&#xff0c;适配个人阅读、校园阅读及大众阅读的个性化需求。系统以SpringBoot为核心开发框架&#xff0c;整…

作者头像 李华
网站建设 2026/2/13 12:24:49

基于multisim仿真的直流稳压电源设计

设计一个直流稳压电路&#xff0c;将220V的市压转变为5V的直流电。 性能指标&#xff1a; 1、输出电压&#xff1a;5V 2、最大输出电流&#xff1a;0.5A 3、电压调整率&#xff1a;<4% 4、电流调整率&#xff1a;<4% 5、波纹系数&#xff1a;<5% 仿真图&#xff1a; …

作者头像 李华