제가 이해하는 한가지 마스터 프로세스는 다른 모든 프로세스에 메시지를 보냅니다. 모든 다른 프로세스는 마스터 프로세스에 메시지를 보냅니다. 이것이 장벽이 작용하기에 충분한가? 그렇지 않다면 무엇이 더 필요합니까?메시지 전달 시스템에서 장벽은 어떻게 구현됩니까?
답변
OpenMPI's implementation of barrier을 살펴 보겠습니다. 다른 구현은 약간 다를 수 있지만 일반적인 통신 패턴은 동일해야합니다.
MPI의 장벽은 설정 비용이 없다는 것입니다. MPI_Barrier
호출에 도달하는 프로세스는 그룹의 다른 모든 구성원도 MPI_Barrier
을 호출 할 때까지 차단됩니다. MPI는 에 동일한 호출에 도달 할 것을 요구하지 않으며, MPI_Barrier
에 대한 호출 만 필요합니다. 따라서 그룹의 총 노드 수가 이미 각 프로세스에 알려지기 때문에 호출을 초기화하기 위해 추가 상태를 배포 할 필요가 없습니다. 이제
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
* [...]
*/
[...]
/*
* barrier_intra_lin
*
* Function: - barrier using O(N) algorithm
* Accepts: - same as MPI_Barrier()
* Returns: - MPI_SUCCESS or error code
*/
int
mca_coll_basic_barrier_intra_lin(struct ompi_communicator_t *comm,
mca_coll_base_module_t *module)
{
int i;
int err;
int size = ompi_comm_size(comm);
int rank = ompi_comm_rank(comm);
먼저 보내 그들이 루트 노드로 장벽에 도달 통지 (순위 0 하나의 루트 노드를 제외한) 모든 노드 :
/* All non-root send & receive zero-length message. */
if (rank > 0) {
err =
MCA_PML_CALL(send
(NULL, 0, MPI_BYTE, 0, MCA_COLL_BASE_TAG_BARRIER,
MCA_PML_BASE_SEND_STANDARD, comm));
if (MPI_SUCCESS != err) {
return err;
}
후 그들은 루트에서 통지를 기다리고 차단하는 것이 :
err =
MCA_PML_CALL(recv
(NULL, 0, MPI_BYTE, 0, MCA_COLL_BASE_TAG_BARRIER,
comm, MPI_STATUS_IGNORE));
if (MPI_SUCCESS != err) {
return err;
}
}
루트 노드 메신저 의사 소통의 다른 측면을 즐겁게합니다. (그는 이미 장벽 호출 내부에 있기 때문에, 자신을 제외한 그룹의 모든 노드에서 하나를) 먼저 블록이 n-1
통지를받은 때까지 일단 모든 알림이 도착했습니다
else {
for (i = 1; i < size; ++i) {
err = MCA_PML_CALL(recv(NULL, 0, MPI_BYTE, MPI_ANY_SOURCE,
MCA_COLL_BASE_TAG_BARRIER,
comm, MPI_STATUS_IGNORE));
if (MPI_SUCCESS != err) {
return err;
}
}
, 그것은 메시지를 보내는 모든
for (i = 1; i < size; ++i) {
err =
MCA_PML_CALL(send
(NULL, 0, MPI_BYTE, i,
MCA_COLL_BASE_TAG_BARRIER,
MCA_PML_BASE_SEND_STANDARD, comm));
if (MPI_SUCCESS != err) {
return err;
}
}
}
/* All done */
return MPI_SUCCESS;
}
그래서 통신 패턴 먼저 다음 루트에 모든 노드에서 n:1
루트에서 1:n
입니다 : 노드는 모든 사람이이 장벽 호출 자체를 잎 그 후에 장벽을, 도달했음을 신호, 기다리고 있습니다 모든 노드로 되돌아갑니다. 루트 노드에 요청이 과부하되는 것을 피하기 위해 OpenMPI는 트리 기반 통신 패턴을 사용할 수 있지만 기본적인 아이디어는 같습니다. 모든 노드는 장벽에 들어갈 때 루트에 알립니다. 루트는 결과를 집계하고 모든 사람들에게 알려줍니다. 계속할 준비가되었습니다.
그런 명확한 설명에 감사드립니다. :). – MetallicPriest
아니요, 충분하지 않습니다. 마스터 프로세스가 장벽에 도달했음을 알리는 다른 모든 프로세스에 메시지를 보내고 다른 모든 프로세스가 장벽에 도달했다는 응답을하면 마스터 프로세스 만 모든 프로세스가 장벽에 도달했음을 알게됩니다. 이 시나리오에서는 마스터에서 다른 프로세스로의 또 다른 메시지가 필요합니다.
나는 모든 도서관에서 MPI 장벽의 실제 구현에 대해 아무런 주장도하지 않고 있는데, 특히 내가 설명한 메시지 순서가 이론 상으로는 부족하다는 점을 암시하는 것은 아니다.
마스터가 처음 수신 한 후 전송합니다.나도 처음 읽는 동안 조건 (계급> 0)을 간과했다. –
"장벽이 작동하기에 충분합니까?" -- 작동합니까? 시도해 봤어? 어떤 문제가 있습니까? "그렇지 않다면 더 필요한 것은 무엇인가?" - 우리 한테 말해. – Shoe
수신 된 각 완료 메시지 (클라이언트가 보낸 다음 차단)에 대해 마스터는 다음과 같이 실행합니다. – Damon