MPI可以实现一对多的集合通信,最常用的是广播:某个进程将数据广播到所有其他进程,最终的结果就是每个进程都有一份广播的数据。MPICH中的广播函数是MPI_Bcast(void* buffer,intcount,MPI_Datatype datatype,int root, MPI_Comm comm)。该函数在使用过程中非常容易出错,在此我们通过具体实例来说明其使用方法。

MPI_Bcast和MPI_Send不同

对广播最直观的观点是某个特定进程将数据一一广播到所有的进程,所以很多人在使用MPI_Bcast函数的时候,总是将其放入一个if语句中,由要发送数据的进程单独执行。但这是错误的!由某个特定进程发送数据到所有其他进行是低效的,复杂度为O(n),所以MPI_Bcast函数在实现的时候往往采用更加高效的手段进行广播。一个最常用也是非常高效的手段是规约树广播:收到广播数据的所有进程都参与到数据广播的过程中。首先只有一个进程有数据,然后它广播到某个进程,此时有两个进程有数据;然后这两个进程都参与到下一次的广播中,这时就会有4个进程有数据,……,以此类推,每次都会有2的次方个进程有数据。通过这种规约树的广播方法,广播的复杂度降为O(log
n)。当然针对不同的数据大小,MPI_Bcast函数采取了不同的广播策略。

由上面的解释,我们可以明白在广播的过程中,所有的进程都参与广播,并不只有最初的进程进行发送(它只是一个起点)。所以我们在使用MPI_Bcast函数的时候一定要将其放到所有进程都能运行的位置。

动态数组的广播

有时我们要广播的数据长度并不知道,这时就需要采用动态分配的方式分配数据,然后再将其广播。这里很容易出问题,问题的根本就是MPI程序是分布式程序,即使我们在写程序时所有的进程都公用相同的变量,但是在不同的进程下它们的含义不同。这就会导致有些进程的指针变量指向一块已经分配内存的空间,但是有些进程的指令变量还是空指针。这时如果不注意,就会导致动态数组广播的失败。

在下面的实例中,master进程从用户读取一个长度,然后利用malloc分配空间并赋值,然后将该数组广播到其他slave进程。方法是首先广播数组的长度,然后让slave进程分配相应的内存,最后再广播该数组。

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h> #define MASTER 0 int main(int argc,char *argv[])
{
int myid, numprocs;
float *sequence;
int length; MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid); if(myid==MASTER)
{
scanf(“%d”,&length);
sequence=(float*)malloc(sizeof(float)*length); for(int i=0;i<length;i++)
{
sequence[i]=i;
}
} /* step 1
* broadcast the length first
*/
MPI_Bcast(&length,1,MPI_INT,MASTER,MPI_COMM_WORLD); /* step 2
* allocate space on the slave processes
*/
if(myid!=MASTER)
{
sequence =(float*)malloc(sizeof(float)* length);
} /* step 3
* broadcast the sequence to all the processes
*/
MPI_Bcast(sequence, length,MPI_FLOAT,MASTER,MPI_COMM_WORLD); printf("process %d get the sequnce, length %d\n",myid, length); MPI_Finalize();
return 0;
}

通过上面三步,我们就完成了对动态数组的广播。上面的实例可以很容易扩展到结构体和其他需要动态分配内存的广播程序中。核心就是三步:1)广播长度;2)分配空间;3)广播动态数组。

上面是针对MPI广播中常见问题的解析,后续会对非基本数据类型的广播做介绍。

mpi中的广播的更多相关文章

  1. android中的广播接收实现总结

    1 首先根据广播应用内接收和应用外接收,分两个类进行管理[1]  LocalBroadcastManager,应用内广播管理类[2]  BroadcastManager  广播管理类(部分应用内,应用 ...

  2. Android系统中的广播(Broadcast)机制简要介绍和学习计划

    在Android系统中,广播(Broadcast)是在组件之间传播数据(Intent)的一种机制:这些组件甚至是可以位于不同的进程中,这样它就像Binder机制一样,起到进程间通信的作用:本文通过一个 ...

  3. Android中使用广播机制退出多个Activity

    谷歌百度一下,Android中退出多个Activity的方法,大家讨论的很多. 在实习的时候,看到公司的项目退出多个Activity,是采用LinkedList方法,毕业设计的时候,也参照了那种方法. ...

  4. Android中的广播

    Android中的广播 广播接受器,可以比喻成收音机.而广播则可以看成电台. Android系统内部相当于已经有一个电台 定义了好多的广播事件,比如外拨电话 短信到来 sd卡状态 电池电量变化... ...

  5. Apache Flink中的广播状态实用指南

    感谢英文原文作者:https://data-artisans.com/blog/a-practical-guide-to-broadcast-state-in-apache-flink 不过,原文最近 ...

  6. Android 中的广播(Broadcast)

    Android 广播(broadcast) 饮水思源 本文章内容学习和总结自 郭霖大神:<Android第一行代码> Overview 就像我们的学校里的喇叭一样,是用来通知的.而Andr ...

  7. Android 中的广播机制

    Android 中的广播机制 Android 中的广播,按照广播响应范围,可以分为应用内广播和全局广播.按照广播的接收方式,可以分为标准广播和有序广播. 广播的分类 响应范围 应用内广播:此类广播只能 ...

  8. spark中的广播变量broadcast

    Spark中的Broadcast处理 首先先来看一看broadcast的使用代码: val values = List[Int](1,2,3) val broadcastValues = sparkC ...

  9. 吴恩达深度学习:python中的广播

    1.python中的广播: (1)广播是一种手段,可以让python代码执行得更快,我们来看看python实际如何执行. 下面矩阵列出了100克苹果.牛肉.鸡蛋和蛋白质中含有的碳水化合物.蛋白质和脂肪 ...

随机推荐

  1. 什么是 Docker

    Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux 基金会,遵从了 ...

  2. 解读Batch Normalization

    原文转自:http://blog.csdn.net/shuzfan/article/details/50723877 本次所讲的内容为Batch Normalization,简称BN,来源于<B ...

  3. springMVC源码分析--RequestToViewNameTranslator请求到视图名称的转换

    RequestToViewNameTranslator可以在处理器返回的View为空时使用它根据Request获取viewName.RequestToViewNameTranslator提供的实现类只 ...

  4. CentOS7下安装GitLab

    三步在CentOS7系统下,完成GitLab的安装. 1.安装和配置必须的依赖 sudo yum install curl policycoreutils openssh-server openssh ...

  5. PLSQL实现分页查询

    --集合实现游标查询 CREATE OR REPLACE PACKAGE emppkg IS TYPE t_record IS RECORD( rn INT, empno emp.empno%TYPE ...

  6. RxJava操作符(02-创建操作)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51645348 本文出自:[openXu的博客] 目录: Create Defer Empty ...

  7. 如何构建Android MVVM 应用框架

    概述 说到Android MVVM,相信大家都会想到Google 2015年推出的DataBinding框架.然而两者的概念是不一样的,不能混为一谈.MVVM是一种架构模式,而DataBinding是 ...

  8. linux shell bash使用管道|和read结合时问题解决

    最近在将ksh转成bash运行的时候出现了问题.代码如下: echo $1 | sed 's/\..*$/''/' | read FILE_NAME 当使用ksh执行的时候没有问题,FILE_NAME ...

  9. Fragment的事务操作&Actvity的状态丢失

    Fragment Transactions & Activity State Loss 本文翻译自Fragment Transactions & Activity State Loss ...

  10. 如何找到java对应的c/c++源码

    很多时候java经常被c鄙视,因为c说我是你的基础,但java竟然有如此强的生命力就必然有其存在的价值.本文不探讨各种开发语言的优劣,仅仅介绍如何找到java对应c/c++实现的源码.当我们追究一个j ...