并行程序设计基础——组通信(3)

目录

一、组归约

二、归约并散发

三、扫描

四、π值计算

五、不同类型归约操作的对比

六、不正确的组通信方式

七、MINLOC和MAXLOC

八、用户自定义归约操作

九、小结


        前两节我们介绍了组通信中常用的一对多、多对一以及多对多接口调用,本节继续对其余组通信操作进行介绍。同时,利用其中的多个组通信接口实现了π值的并行计算。

一、组归约

        组归约MPI_ALLREDUCE就相当于组中每一个进程都作为ROOT分别进行了一次归约操作。即归约的结果不只是某一个进程拥有,而是所有的进程都拥有。它在某种程度上和组收集与收集的关系很相似。

MPI_ALLREDUCE(sendbuf, recvbuf, count, datatype, op, comm)
IN    sendbuf        发送消息缓冲区的起始地址(可选数据类型)
OUT   recvbuf        接收消息缓冲区的起始地址(可选数据类型)
IN    count          发送消息缓冲区中的数据个数(整型)
IN    datatype       发送消息缓冲区中的数据类型(句柄)
IN    op             操作(句柄)
IN    comm           通信域(句柄)

//c语言的说明
int MPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
//Fortran语言的说明
MPI_ALLREDUCE(SENDUBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER  COUNT, DATATYPE, OP, COMM, IERROR

二、归约并散发

        MPI_REDUCE_SCATTER操作可以认为是MPI对每个归约操作的变形,它将归约结果分散到组内的所有进程中去,而不是仅仅归约到ROOT进程。

MPI_REDUCE_SCATTER(sendbuf, recvbuf, recvcounts, datatype, op, comm)
IN    sendbuf        发送消息缓冲区的起始地址(可选数据类型)
OUT   recvbuf        接收消息缓冲区的起始地址(可选数据类型)
IN    recvcounts     接收数据个数(整型数组)
IN    datatype       发送消息缓冲区中的数据类型(句柄)
IN    op             操作(句柄)
IN    comm           通信域(句柄)

//c语言的说明
int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
//Fortran语言的说明
MPI_REDUCE_SCATTER(SENDUBUF, RECVBUF, RECVCOUNTS, DATATYPE, OP, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER  RECVCOUNTS(*), DATATYPE, OP, COMM, IERROR

        MPI_REDUCE_SCATTER对由sendbuf、count和datatype定义的发送缓冲区数组的元素逐个进行归约操作,发送缓冲区数组的长度count=∑irecvcount[i]。然后,将结果数组的前recvcounts[0]个元素送给进程0的接收缓冲区,再将接下来的recvcounts[1]个元素送给进程1的接收缓冲区,以此类推,最后将最后的recvcounts[N-1]个元素送给进程N-1的接收缓冲区。

三、扫描

        可以将扫描看作是一种特殊的归约,即每一个进程都对排在它前面的进程进行归约操作。MPI_SCAN调用的结果是,对于每一个进程i,它对进程0,……,i的发送缓冲区的数据进行指定的归约操作,结果存入进程i的接收缓冲区。

MPI_SCAN(sendbuf, recvbuf, count, datatype, op, comm)
IN    sendbuf        发送消息缓冲区的起始地址(可选数据类型)
OUT   recvbuf        接收消息缓冲区的起始地址(可选数据类型)
IN    count          输入缓冲区中元素的个数(整型)
IN    datatype       输入缓冲区中元素的类型(句柄)
IN    op             操作(句柄)
IN    comm           通信域(句柄)

//c语言的说明
int MPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype, MPI_Op op, MPI_Comm comm)
//Fortran语言的说明
MPI_SCAN(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER  COUNT, DATATYPE, OP, COMM, IERROR

        也可以换一种角度,将扫描操作看作是每一个进程i发送缓冲区中的数据与它前面的进程i-1接收缓冲区中的数据进行指定的归约操作后,将结果存入进程i的接收缓冲区;而进程i接收缓冲区中的数据用来和进程i+1发送缓冲区中的数据进行归约。进程0接收缓冲区中的数据就是发送缓冲区的数据。

四、π值计算

        π值计算具有很好的并行性,这里我们利用组通信的广播、规约操作对π值并行计算进行实现。(采用C++编写程序)

        有积分公式如下:

\int_{0}^{1}\frac{1}{1+x^{2}}dx = arctan(x)|_{0}^{1} = arctan(1) - arctan(0) = arctan(1) = \frac{\pi}{4}

        令函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿核试Bug愁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值