2011-04-27 4 views
2

일부 MPI 사양을 읽은 후에는 MPI_THREAD_SERIALIZED로 초기화 할 때 프로그램이 별도의 스레드에서 발생하는 MPI_Send/Recv 호출이 겹치지 않아야 함을 이해해야합니다. 즉, MPI 호출을 보호하기 위해 뮤텍스가 필요합니다. pthread가있는 MPI_THREAD_SERIALIZED의 올바른 사용

는 이러한 상황을 고려해

Mutex mpi_lock = MUTEX_INITIALIZER; 

void thread1_function(){ 
    while(true){ 
     /* things happen */ 

     lock(mpi_lock); 
     MPI_Send(/* some message */); 
     unlock(mpi_lock); 

     /* eventually break out of loop */ 
    } 
} 

void thread2_function(){ 
    while(true){ 
     /* things happen */ 

     char *buffer = CREATE_BUFFER(); 
     lock(mpi_lock); 
     MPI_Recv(buffer /* some message stored in buffer */); 
     unlock(mpi_lock); 

     /* eventually break out of loop */ 
    } 
} 

int main(){ 
    create_thread(thread1_function); 
    create_thread(thread2_function); 

    return 0; 
} 

여기 내 질문이있다 :이 올바른 방법인가 및/또는이 필요하다? 제 상황에서는 thread2_function()에서받은 메시지 사이에 큰 시간 간격이있을 수 있다고 가정해야합니다. thread1_function()이 thread2_function()이 송신을 수행하기 전에 수신을 완료하기를 기다릴 필요가 없도록하는 방법이 있습니까?

나는 MPI_THREAD_MULTIPLE에 대해 이미 알고 있지만 시스템 제약 조건은이 기능을 사용할 수 없다는 것을 의미합니다.

코드 구조 조정을위한 제안이 있지만 내 목표는 끊임없이 작동하는 "메인"스레드와 인터럽트없이 MPI_Send의 결과를 갖는 것입니다. 다른 스레드는 메인 스레드의 큐에 대한 수신 및 추가를 관리합니다 .

미리 감사드립니다.

답변

2

MPI_THREAD_SERIALIZED 만 사용하는 경우 이러한 외부 잠금 (또는 다른 유사한 동기화 구성표)이 매우 필요합니다. 주변을 둘러 볼 수있는 유일한 방법은 MPI_THREAD_MULTIPLE을 사용하는 것이지만 사용할 수없는 것 같습니다. 또한이 상황에서 SERIALIZED 대신 MPI_THREAD_SINGLE 또는 MPI_THREAD_FUNNELED을 사용하지 마십시오. 일부 MPI가 손상 될 수있는 플랫폼과 구현이 있습니다.

프로세스 내에있는 스레드간에 메시지를 보내거나받는 경우 위에 게시 한 코드에 문제가있을 수 있습니다. thread2이 실행되면 잠금을 획득하고 thread1이 잠금을 획득하고 MPI_Send을 통해 thread2에 메시지를 게시하기 전에 thread1이 잠금을 획득 할 수 없으므로 교착 상태가 발생합니다. 잠금을 획득하는 데 방해가되는 프로세스간에 메시지 (프로세스/스레드 간 방향 그래프로 메시지 전송을 볼 때)가있는 경우 비슷한 교착 상태가 발생할 수 있습니다.

이러한 종류의 시나리오에서 교착 상태를 피하려면 가능한 한 MPI 호출 차단을 차단하고 MPI_IrecvMPI_Test과 같은 비 차단 호출을 사용하는 것이 좋습니다.