当前位置: 首页 > news >正文

MPI_Win_allocate_shared介绍和使用

文章目录

  • MPI_Win_allocate_shared 详解 + 幽灵单元(Ghost Cell)交换完整示例
    • 一、核心概念
      • 1. 函数作用
      • 2. 函数原型
      • 3. 关键特性
    • 二、幽灵单元(Ghost Cell)交换场景
      • 1. 场景说明
      • 2. 优势
    • 三、完整代码实现(C语言)
      • 代码逻辑
    • 四、代码关键细节解析
      • 1. 共享通信域创建
      • 2. 共享内存分配
      • 3. 邻居地址查询
      • 4. 窗口同步
    • 五、编译与运行
      • 编译(MPI编译器)
      • 运行(同节点运行3个进程)
      • 输出示例
    • 六、核心优势与适用场景
      • 优势
      • 适用场景
      • 限制
      • 总结

MPI_Win_allocate_shared 详解 + 幽灵单元(Ghost Cell)交换完整示例

MPI_Win_allocate_sharedMPI-3 标准引入的单边通信(RMA)核心函数,专门用于同节点共享内存场景,能让同一计算节点上的 MPI 进程直接读写彼此的内存,无需消息传递,性能远高于传统MPI_Send/Recv

一、核心概念

1. 函数作用

为**共享内存通信域(通常是同一节点)**内的所有进程,集体分配一段内存:

  • 调用进程拥有本地内存段(可直接读写)
  • 同节点其他进程可通过MPI 单边RMA操作直接访问这段内存
  • 无需拷贝数据,直接内存访问,极致高效

2. 函数原型

intMPI_Win_allocate_shared(MPI_Aint size,// 本地分配的内存大小(字节)intdisp_unit,// 地址偏移单位(通常=1,字节对齐)MPI_Info info,// 优化信息(通常MPI_INFO_NULL)MPI_Comm comm,// 共享内存通信域(必须是节点内共享子通信域)void*baseptr,// 输出:本地内存段起始地址MPI_Win*win// 输出:创建的共享内存窗口对象);

3. 关键特性

  1. 集体操作:共享通信域内所有进程必须同时调用
  2. 节点内有效:只能在同一NUMA节点/计算节点的进程间共享
  3. 零拷贝:直接访问物理内存,无中间缓冲区
  4. 配套APIMPI_Win_shared_query(查询其他进程的共享内存地址)

二、幽灵单元(Ghost Cell)交换场景

1. 场景说明

一维区域分解

  • 每个进程负责一段主数据(data[1]~data[size]
  • 左右各1个幽灵单元data[0]=左幽灵,data[size+1]=右幽灵)
  • 需求:左幽灵 ← 左邻居的最后一个主数据;右幽灵 ← 右邻居的第一个主数据

2. 优势

传统MPI需要Send/Recv收发数据,而MPI_Win_allocate_shared

  • 直接内存读写,无消息开销
  • 代码更简洁,适合同节点并行

三、完整代码实现(C语言)

代码逻辑

  1. 创建节点内共享内存通信域comm_shm
  2. MPI_Win_allocate_shared分配带幽灵单元的共享数组
  3. MPI_Win_shared_query获取邻居的共享内存地址
  4. 直接内存赋值完成幽灵单元交换(无MPI收发)
  5. 同步窗口、释放资源
#include<stdio.h>#include<stdlib.h>#include<mpi.h>// 每个进程的主数据长度(不含幽灵单元)#defineDATA_SIZE4intmain(intargc,char**argv){MPI_Init(&argc,&argv);intrank,size;MPI_Comm_rank(MPI_COMM_WORLD,&rank);MPI_Comm_size(MPI_COMM_WORLD,&size);// ===================== 步骤1:创建节点内共享内存通信域 =====================MPI_Comm comm_shm;// 按物理节点拆分通信域,同节点进程在同一个comm_shm中MPI_Comm_split_type(MPI_COMM_WORLD,MPI_COMM_TYPE_SHARED,// 按共享内存节点拆分rank,MPI_INFO_NULL,&comm_shm);intshm_rank,shm_size;MPI_Comm_rank(comm_shm,&shm_rank);MPI_Comm_size(comm_shm,&shm_size);// ===================== 步骤2:分配共享内存(含2个幽灵单元) =====================// 总长度:左幽灵(1) + 主数据(DATA_SIZE) + 右幽灵(1)inttotal_len=DATA_SIZE+2;MPI_Aint shm_size_bytes=total_len*sizeof(int);// 总字节数int*local_data;// 本地共享内存指针MPI_Win shm_win;// 共享内存窗口// 集体分配共享内存MPI_Win_allocate_shared(shm_size_bytes,// 本地内存大小sizeof(int),// 偏移单位:按int对齐MPI_INFO_NULL,comm_shm,&local_data,// 输出本地内存地址&shm_win// 输出窗口);// ===================== 步骤3:初始化本地数据 =====================// local_data[0] = 左幽灵单元// local_data[1~DATA_SIZE] = 主数据// local_data[DATA_SIZE+1] = 右幽灵单元for(inti=1;i<=DATA_SIZE;i++){local_data[i]=rank*10+i;// 方便识别数据归属}local_data[0]=-1;// 初始左幽灵local_data[DATA_SIZE+1]=-1;// 初始右幽灵// ===================== 步骤4:获取左右邻居的共享内存地址 =====================intleft_rank=(shm_rank-1+shm_size)%shm_size;// 左邻居intright_rank=(shm_rank+1)%shm_size;// 右邻居int*left_neigh_data=NULL;// 左邻居共享内存地址int*right_neigh_data=NULL;// 右邻居共享内存地址MPI_Aint query_size;intquery_disp_unit;// 查询左邻居的共享内存基地址MPI_Win_shared_query(shm_win,left_rank,&query_size,&query_disp_unit,&left_neigh_data);// 查询右邻居的共享内存基地址MPI_Win_shared_query(shm_win,right_rank,&query_size,&query_disp_unit,&right_neigh_data);// ===================== 步骤5:直接内存交换幽灵单元(核心!) =====================// 开启RMA访问窗口MPI_Win_fence(0,shm_win);// 1. 左幽灵 = 左邻居的最后一个主数据local_data[0]=left_neigh_data[DATA_SIZE];// 2. 右幽灵 = 右邻居的第一个主数据local_data[DATA_SIZE+1]=right_neigh_data[1];// 同步所有进程的内存访问MPI_Win_fence(0,shm_win);// ===================== 步骤6:打印结果 =====================printf("[进程 %d] 数据:幽灵左=%d, 主数据=[%d,%d,%d,%d], 幽灵右=%d\n",rank,local_data[0],local_data[1],local_data[2],local_data[3],local_data[4],local_data[DATA_SIZE+1]);// ===================== 步骤7:释放资源 =====================MPI_Win_free(&shm_win);MPI_Comm_free(&comm_shm);MPI_Finalize();return0;}

四、代码关键细节解析

1. 共享通信域创建

MPI_Comm_split_type(..., MPI_COMM_TYPE_SHARED, ...)

  • 自动将全局通信域拆分为物理节点内的子通信域
  • 只有同节点进程能共享内存,跨节点不支持

2. 共享内存分配

MPI_Win_allocate_shared

  • 第二个参数disp_unit=sizeof(int):地址偏移按int单位计算,更安全
  • local_data本地直接可用的指针,和普通数组无区别

3. 邻居地址查询

MPI_Win_shared_query

  • 输入窗口+目标进程rank
  • 输出目标进程的共享内存起始指针
  • 拿到指针后,直接赋值即可交换数据,无任何MPI收发

4. 窗口同步

MPI_Win_fence

  • 集体同步函数,确保所有进程的内存访问完成
  • 必须在共享内存读写前后调用,保证数据一致性

五、编译与运行

编译(MPI编译器)

mpicc-oshm_ghost shm_ghost.c

运行(同节点运行3个进程)

mpirun-n3./shm_ghost

输出示例

[进程 0] 数据:幽灵左=24, 主数据=[1,2,3,4], 幽灵右=11 [进程 1] 数据:幽灵左=4, 主数据=[11,12,13,14], 幽灵右=21 [进程 2] 数据:幽灵左=14, 主数据=[21,22,23,24], 幽灵右=1
  • 进程0的左幽灵=进程2的最后一个主数据(24)
  • 进程0的右幽灵=进程1的第一个主数据(11)
  • 幽灵单元交换完成!

六、核心优势与适用场景

优势

  1. 性能极高:零拷贝、直接内存访问,比Send/Recv快5~10倍
  2. 代码简洁:无需处理消息收发、标签、匹配问题
  3. 原生支持:MPI-3标准,主流MPI库(OpenMPI、MPICH)全支持

适用场景

  1. 同节点多进程并行(CPU多核、节点内并行)
  2. 数值模拟:幽灵单元交换、边界数据更新
  3. 共享内存架构下的高频数据交互

限制

  • 仅支持同一物理节点的进程,跨节点必须配合传统MPI通信
  • 必须集体调用,不能单独执行

总结

  1. MPI_Win_allocate_shared节点内共享内存+单边通信的最优方案
  2. 幽灵单元交换:查询邻居地址 → 直接内存赋值 → 窗口同步,无收发
  3. 代码可直接用于一维/二维/三维数值模拟的边界数据交换
  4. 同节点场景下,性能远超传统MPI点对点通信
http://www.gsyq.cn/news/1351783.html

相关文章:

  • ops-softmax:Transformer 推理中的概率归一化引擎
  • OpenClaw:高效管理分布式Agent开发团队
  • C# 基于OpenCv的视觉工作流-章76-轮廓-段距
  • 从手机到机器人:拆解RGB-D摄像头(如Kinect、RealSense)如何‘看见’三维世界
  • TIPTOP ERP开发环境搭建保姆级教程:从零配置Genero Studio 2.40.11到汉化
  • 手机屏幕越来越高清,MIPI接口扛不住了?聊聊DSC压缩技术如何帮你省下硬件成本
  • Newman安装之nodejs下载安装
  • 从ENVI到MATLAB:高光谱图像处理工作流迁移指南(以真假彩色显示为例)
  • 避开EI投稿的‘乱码坑’与‘格式雷’:从作者信息填写到PDF Express通关指南
  • 从SolidWorks到ROS:如何用DH参数为遨博E5机械臂生成URDF模型?
  • pto-isa:昇腾 Graph Compiler 的虚拟指令集
  • Triton + CANN GE Backend:大模型推理服务部署
  • cann-learning-hub:从零开始学昇腾的最短路径
  • 核聚变ECEi数据压缩与GPU加速优化实践
  • Keil MDK中第三方软件包兼容性问题解析与解决
  • 为什么你的 AI 应用做不成 Agent
  • FPGA开发避坑实录:我在Quartus II里用LPM_ROM做信号发生器时踩过的那些‘雷’
  • 嘉立创EDA专业版安装避坑指南:从下载到第一个ESP32项目实战
  • 从B73到5000个RILs:手把手拆解玉米NAM群体构建的完整流程与关键决策
  • ChatGPT生成的SQL注入漏洞代码竟通过了87%静态扫描器?安全团队紧急避坑指南(含检测脚本)
  • Chromium 146 编译指南 Windows篇:Git 安装与高级配置(二)
  • 2026年Q2简阳冷库安装市场:专业本地服务商的价值凸显 - 2026年企业推荐榜
  • 长沙短视频拍摄引流哪家更值得信赖
  • C51编译器浮点数支持与嵌入式优化实践
  • ngx_http_set_virtual_server
  • 服务器末级缓存管理优化与Garibaldi架构解析
  • taotoken的审计日志功能让我们清晰追踪了每一次api调用
  • ChatGPT自动提炼FAQ的3层过滤机制:语义去重→意图归类→合规校验,附Python+LangChain实现代码
  • 从 0 到 1:用魔珐星云打造真实可用的智能健身私教【技术原理文章】
  • 搞定环境一致性神器:Linux 环境下 Docker 新手入门全攻略