代码文件:test5.c
#include "mpi.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv)
{
int rank,size,i;
int *arr = NULL;
int len = 6;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
arr = (int*)malloc(len*sizeof(int));
memset(arr, 0, sizeof(int)*len);
if(rank == 0)
{
for(i = 0; i < len; i++)
arr[i] = i + 1;
}
MPI_Bcast(arr, len, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
if(rank != 0)
{
printf("In process %d...n", rank);
for(i = 0; i < len; i++)
printf("arr[%d]=%dt", i, arr[i]);
}
free(arr);
MPI_Finalize();
return 0;
}
1)在语义上,可以认为MPI_Bcast是一个“多次发送”的过程,这是没有错误的,但在语法上,不可以将MPI_Bcast等同为多个MPI_Send语句,因此,在MPI程序中,就不能用MPI_Recv去和MPI_Bcast相匹配。
2)MPI_Bcast是组操作,在每一个进程中都必须有相应的MPI_Bcast语句,而不是MPI_Recv语句。
3)由上面的程序,可以看出MPI_Bcast函数处于所有进程的执行流程中。且对于所有进程来说,广播进程(0进程)和其他进程之间的发送/接收缓冲区名字是一致的,如本程序中都是arr,看过的其他程序中也仍然存在这种一致性,这也许是MPI中对MPI_Bcast的一种约定俗成?
带着3)中的疑问,我们不妨将程序test5.c中对数组arr分配内存的部分放到主进程(0进程)中,即:
if(rank == 0)
{
arr = (int*)malloc(len*sizeof(int));
memset(arr, 0, sizeof(int)*len);
for(i = 0; i < len; i++)
arr[i] = i + 1;
}
然后编译,运行程序,启动两个进程,然后输出的运行结果为:
=====================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 11
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
=====================================================================================
APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
程序运行错误,错误字串为:Segmentation fault(根据经验,这是引用了未分配的内存所造成的)
因为,将对数组arr内存分配的代码放到主进程(0进程)中后,从进程将无法对arr分配内存,而又要执行MPI_Bcast函数接收主进程发送过来的数据而引用未分配的内存空间,所以产生Segmentation fault错误