2011-02-04 9 views
0

왜 장벽이 작동하지 않습니까? 내가 그것을 사용하는 경우, 프로그램이, 그렇지 않으면 내가 이상한 순서로 출력을 얻을 차단됩니다 : 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 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 

코드 :

#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(); 

}

답변

3

MPI_Barrier이 집단 통신 호출입니다 : 그것은 것입니다 매개 변수로 제공된 통신 기의 모든 프로세스가 호출 할 때까지 차단하십시오. 작업자 프로세스는 결코 MPI_Barrier를 호출하지 않으므로 마스터는 무기한으로 차단합니다.

+0

좋아, 그럼 워커 작업 끝에 MPI_BARRIER를 추가했는데 이제 모든 것이 정상적으로 작동하는 것 같습니다. 이제 장벽을 사용할 때 성능 저하가 발생하는지 궁금합니다. – flow

+1

장벽을 사용할 때 성능 저하가 있지만 올바른 동작을 위해 프로세스를 동기화해야하는 경우에는 필요합니다. 병렬 알고리즘을 최적화하는 한 가지 측면은 동기화가 필요하지 않도록 코드를 설계하는 것입니다. –

+0

@Werner : 글쎄요, Barrier는 성능을 해치고 향상시키지 못합니다. 반면에, 그것은 당신이 개발자로서보다 편리하게 만들 수 있습니다. 다른 프로세스가 다른 프로세스가 특정 작업을 완료 할 때까지 프로세스가 의미있는 작업을 수행하지 못할 수 있으므로 Barrier가 반드시 필요합니다. Barrier가 필요한지 또는 성능 손실이 허용되는지를 판단하는 것은 사용자의 몫입니다. – suszterpatt