C MPI_屏障不工作
为什么这里的屏障不起作用?如果我使用它,程序会被阻塞,否则我会以奇怪的顺序获得输出:C MPI_屏障不工作,c,mpi,barrier,C,Mpi,Barrier,为什么这里的屏障不起作用?如果我使用它,程序会被阻塞,否则我会以奇怪的顺序获得输出: Number of worker tasks = 4 sending 1-th element q=0.011000 to task 1 sending 2-th element q=0.012000 to task 2 received 1-th element q=0.011000 in task 1 processed 1-th element q=6.105000 in task
Number of worker tasks = 4
sending 1-th element q=0.011000 to task 1
sending 2-th element q=0.012000 to task 2
received 1-th element q=0.011000 in task 1
processed 1-th element q=6.105000 in task 1
sending 3-th element q=0.013000 to task 3
received 2-th element q=0.012000 in task 2
processed 2-th element q=13.320000 in task 2
sending 4-th element q=0.014000 to task 4
received 3-th element q=0.013000 in task 3
processed 3-th element q=21.645000 in task 3
starting to get data in MASTER
MASTER received 0-th element q=6.105000 from task 1
MASTER received 0-th element q=13.320000 from task 2
received 4-th element q=0.014000 in task 4
processed 4-th element q=31.080000 in task 4
MASTER received 0-th element q=21.645000 from task 3
MASTER received 0-th element q=31.080000 from task 4
end
代码:
#包括“mpi.h”/*所需的mpi库*/
#包括
#包括
#定义矩阵A中的NRRR 16/*行数*/
#定义NLLL 16/*矩阵A中的列数*/
#定义第一个任务的主任务0/*任务ID*/
#从_MASTER 1/*定义设置消息类型*/
#从_WORKER 2/*设置消息类型定义*/
int main(argc、argv)
int-argc;
char*argv[];
{
int numtasks,/*分区中的任务数*/
taskid,/*任务标识符*/
numworkers,/*工人任务数*/
source,/*消息源的任务id*/
目的地,/*消息目的地的任务id*/
mtype,
i、 j,
rc;/*消息类型*/
双qr[NRRR],
ql[NLLL],
元素r[NRRR][3],
元素l[NLLL][3];
MPI_状态;
rc=MPI_Init(&argc,&argv);
rc |=MPI通信大小(MPI通信世界和numtasks);
rc |=MPI通信等级(MPI通信世界和任务ID);
如果(rc!=0)
printf(“初始化MPI和获取任务ID信息时出错\n”);
numworkers=numtasks-1;
//主人
if(taskid==MASTER)
{
printf(“\n\n\n\n工作任务数=%d\n”,numworkers);
//初始化元素和元素
对于(j=0;j是一个集体通信调用:它将阻塞,直到在参数中提供的通信器中的所有进程调用它为止。由于您的工作进程从不调用MPI_屏障,因此主进程将无限期阻塞。是一个集体通信调用:它将阻塞,直到在参数中提供的通信器中的所有进程调用它为止参数调用了它。因为您的工作进程从不调用MPI_屏障,所以主进程将无限期地阻塞。好的,然后我在woker任务结束时添加了MPI_屏障,现在一切似乎都正常。现在我想知道使用屏障时是否会受到性能惩罚使用屏障时会有一些性能惩罚,但它们是必要的evil如果您需要同步进程以获得正确的行为。优化并行算法的一个方面是设计您的代码,使其不需要同步。@Werner:没错,障碍只会损害性能,而不会改善性能。另一方面,它可以使您作为开发人员更方便。在其他情况下,在其他进程完成某些任务之前,进程可能无法执行任何有意义的操作,因此屏障是必不可少的。这取决于您评估是否需要屏障,或者是否可以容忍性能损失。好的,然后我在woker任务的末尾添加了MPI_屏障,现在一切似乎都正常。现在我想知道我f我在使用屏障时会受到性能损失使用屏障时会有一些性能损失,但如果您需要同步进程以获得正确的行为,它们是一个必要的缺点。优化并行算法的一个方面是设计代码,使其不需要同步。@Werner:嗯,这是真的一方面,屏障只会损害性能,而不会提高性能。另一方面,它可以让开发人员更方便。在其他时候,流程可能无法执行任何有意义的操作,直到其他流程完成某些任务,因此屏障是必不可少的。这取决于您评估是否需要屏障,或者性能允许出现异常丢失。
#include "mpi.h" /* required MPI library */
#include <stdio.h>
#include <math.h>
#define NRRR 16 /* number of rows in matrix A */
#define NLLL 16 /* number of columns in matrix A */
#define MASTER 0 /* taskid of first task */
#define FROM_MASTER 1 /* setting a message type */
#define FROM_WORKER 2 /* setting a message type */
int main(argc,argv)
int argc;
char *argv[];
{
int numtasks, /* number of tasks in partition */
taskid, /* a task identifier */
numworkers, /* number of worker tasks */
source, /* task id of message source */
dest, /* task id of message destination */
mtype,
i,j,
rc; /* message type */
double qr[NRRR],
ql[NLLL],
element_r[NRRR][3],
element_l[NLLL][3];
MPI_Status status;
rc = MPI_Init(&argc,&argv);
rc|= MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
rc|= MPI_Comm_rank(MPI_COMM_WORLD,&taskid);
if (rc != 0)
printf ("error initializing MPI and obtaining task ID info\n");
numworkers = numtasks-1;
// MASTER
if (taskid == MASTER)
{
printf("\n\n\n\nNumber of worker tasks = %d\n",numworkers);
// init element_r and element_l
for(j=0;j<NRRR;j++){
element_r[j][0]=j;
element_r[j][1]=j+1;
element_r[j][2]=j+2;
qr[j] = j*1e-4+1e-3;
}
for(i=0;i<NLLL;i++){
element_l[i][0]=12000+i;
element_l[i][1]=12000+i+1;
element_l[i][2]=12000+i+2;
ql[i] = i*1e-3 +1e-2 ;
}
mtype = FROM_MASTER;
for (dest=1; dest<=numworkers; dest++)
{
printf(" sending %d-th element q=%f to task %d\n",dest,ql[dest],dest);
MPI_Send(&ql[dest], 1, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
}
mtype = FROM_WORKER;
printf(" starting to get data in MASTER\n");
for (i=1; i<=numworkers; i++)
{
source = i;
MPI_Recv(&ql[source], 1, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, &status);
}
MPI_Barrier(MPI_COMM_WORLD);
for (i=1; i<=numworkers; i++)
{
source = i;
printf(" MASTER received %d-th element q=%f from task %d\n",taskid,ql[source],source);
}
printf(" end\n");
}
// WORKER
if (taskid > MASTER)
{
mtype = FROM_MASTER;
MPI_Recv(&ql, 1, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status);
printf(" received %d-th element q=%f in task %d\n",taskid,ql[0],taskid);
ql[0]=ql[0]*555*taskid;
printf(" processed %d-th element q=%f in task %d\n",taskid,ql[0],taskid);
mtype = FROM_WORKER;
MPI_Send(&ql, 1, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD);
}
MPI_Finalize();