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容器访问控制

    容器的访问控制,主要通过 Linux 上的 iptables 防火墙来进行管理和实现.iptables 是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 容器要想访问外部 ...

  2. 2016移动端Android新技术综合预览--好文不多,这一篇就足够

    Csdn /Tamic 原文地址: http://blog.csdn.net/sk719887916/article/details/53525067 本文章6月份已完成(http://www.jia ...

  3. 用类模拟C风格的赋值+返回值

    这个方法比较好: class DataHolder: def __init__(self, value=None): self.value = value def set(self, value): ...

  4. Linux动态频率调节系统CPUFreq之一:概述

    随着技术的发展,我们对CPU的处理能力提出了越来越高的需求,芯片厂家也对制造工艺不断地提升.现在的主流PC处理器的主频已经在3GHz左右,就算是智能手机的处理器也已经可以工作在1.5GHz以上,可是我 ...

  5. RxJava操作符(06-错误处理)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51658235 本文出自:[openXu的博客] 目录: Catch Retry 源码下载 1 ...

  6. 在OC代码中创建Swift编写的视图控制器

    背景 近日在和一群朋友做项目,我和另一位同学负责iOS客户端,我是一直使用OC的,而他只会Swift,因此在我们分工协作之后,就需要把代码合在一起,这就牵扯到如何在TabbarController中添 ...

  7. JSP自定义方法库

    如果JSTL的方法库没有满足需要,可以使用自定义方法进行扩展 public class Function{ public static int length(Object obj){ //返回对象的长 ...

  8. Java基础---Java---IO流-----读取键盘录入、InputStreamReader、转换流、OutputStreamWriter、InputStreamReader

    字符流: FileReader FileWriter BufferedReader BufferedWriter 字节流: FileInputStream FileOutputStream Buffe ...

  9. scala学习笔记4(apply方法)

    class ApplyTest{ def apply() = "This apply is in class" def test{ println("test" ...

  10. CSS 控制table 滑动及调整列宽等问题总结

    一. 通过css控制table y方向上滚动 html中没有滚动条,可以根据overflow属性的scroll来对table显示不完全的内容进行滚动. 只是y方向上滚动,很简单,只要设置div的hei ...