2011-03-03 5 views
7

I는 MPI_Barrier의 OpenMPI 실행 구현을 사용하는 몇몇 동기화 문제를 갖는는 OpenMPI MPI_Barrier 문제

int rank; 
int nprocs; 

int rc = MPI_Init(&argc, &argv); 

if(rc != MPI_SUCCESS) { 
    fprintf(stderr, "Unable to set up MPI"); 
    MPI_Abort(MPI_COMM_WORLD, rc); 
} 

MPI_Comm_size(MPI_COMM_WORLD, &nprocs); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 


printf("P%d\n", rank); 
fflush(stdout); 

MPI_Barrier(MPI_COMM_WORLD); 

printf("P%d again\n", rank); 

MPI_Finalize(); 

에 mpirun 용은 -n 2 ./a.out

출력 같아야 P0 P1 .. .

출력 때로는이다 P0 P0 P1 다시 P1 다시

무슨 일 이니?

답변

13

인쇄 출력 라인이 터미널에 나타나는 순서는 반드시 인쇄 순서와 다를 수 있습니다. 공유 리소스 (stdout)를 사용하고 있으므로 항상 주문 문제가 있어야합니다. 여기에서 fflush이 도움이되지 않습니다.

출력에 접두사를 붙이고 모든 파일을 다른 파일 (MPI 프로세스 당 하나씩)에 저장할 수 있습니다.

그런 다음 로그를 검사하기 위해 두 파일을 병합하고 타임 스탬프에 따라 정렬 할 수 있습니다.

그러면 문제가 사라집니다.

+1

클럭 동기화가 보장되지 않으면 MPI 프로세스가 다른 노드에서 실행되는 경우 타임 스탬프를 사용하는 것이 이상적이지 않을 수 있습니다. –

+1

@Shawn : MPI_Wtime()이 있습니다. – suszterpatt

+3

@suszterpatt :'MPI_Wtime()'은 대개 글로벌/동기화 된 시계가 아닙니다! (단지'MPI_WTIME_IS_GLOBAL'이 정의되고 참인 경우입니다) – Zulan

10

MPI_Barrier()에 아무런 문제가 없습니다.

Jens mentioned으로 예상되는 결과가 표시되지 않는 이유는 stdout이 각 프로세스에서 버퍼링되기 때문입니다. 여러 프로세스의 인쇄물이 호출 프로세스에 순서대로 표시된다는 보장은 없습니다. (각 프로세스에서 stdout을 주 프로세스로 전송하여 실시간으로 인쇄 할 경우 많은 불필요한 통신이 발생합니다!)

장벽이 작동한다고 확신하려면 다음과 같이 작성하십시오. 파일 대신. 하나의 파일에 여러 개의 프로세스를 쓰게되면 복잡한 일이 생길 수 있으므로 각 파일을 하나의 파일에 쓰게 한 다음 장벽이 끝나면 쓰는 파일을 서로 바꿀 수 있습니다. 예를 들어 :

Proc-0   Proc-1 
     |     | 
f0.write(..)  f1.write(...) 
     |     | 
     x ~~ barrier ~~ x 
     |     | 
f1.write(..)  f0.write(...) 
     |     | 
    END    END 

샘플 구현 :

#include "mpi.h" 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) { 
    char filename[20]; 
    int rank, size; 
    FILE *fp; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    if (rank < 2) { /* proc 0 and 1 only */ 
     sprintf(filename, "file_%d.out", rank); 
     fp = fopen(filename, "w"); 
     fprintf(fp, "P%d: before Barrier\n", rank); 
     fclose(fp); 
    } 

    MPI_Barrier(MPI_COMM_WORLD); 

    if (rank < 2) { /* proc 0 and 1 only */ 
     sprintf(filename, "file_%d.out", (rank==0)?1:0); 
     fp = fopen(filename, "a"); 
     fprintf(fp, "P%d: after Barrier\n", rank); 
     fclose(fp); 
    } 

    MPI_Finalize(); 
    return 0; 

} 

코드를 실행 한 후, 다음과 같은 결과를 얻어야한다 : 모든 파일에 대해

[[email protected]]$ cat file_0.out 
P0: before Barrier 
P1: after Barrier 

[[email protected]]$ cat file_1.out 
P1: before Barrier 
P0: after Barrier 

은 "후 장벽"문은 것 항상 나중에 나타납니다.

+0

우수 설명 ... :) – RoboAlex

3

출력 순서는 MPI 프로그램에서 보장되지 않습니다.

이것은 MPI_Barrier와 전혀 관련이 없습니다.

또한 MPI 프로그램의 출력 순서에 대해 걱정할 필요가 없습니다.

실제로 이것을 원한다면 프로세스가 메시지를 하나의 순위, 예를 들어 순위 0으로 보내고 순위 0에서받은 메시지를 순서대로 인쇄하도록하는 가장 우아한 방법입니다 계급에 의해.

다시 MPI 프로그램의 출력을 주문하는 데 너무 많은 시간을 소모하지 마십시오. 실용적이지 않고 거의 사용되지 않습니다.