최근 수정 시각 : 2024-06-27 22:49:26

MPI

1. 메세지 패싱 인터페이스(Message Passing Interface)
1.1. 개요1.2. 설명1.3. MPI를 사용하는 라이브러리
2. 내연기관 MPI 엔진3. 일본의 가수

1. 메세지 패싱 인터페이스(Message Passing Interface)

1.1. 개요

C언어로 구현한 MPI Hello World! 예제
#!syntax cpp
#include "mpi.h"
#include <stdio.h>

int main(int argc, char **argv)
{
    int rank, size;
    
    /* Start MPI. */
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    /* Print. */
    if (rank == 0) printf("There are total %d processors.\n", size);
    printf("\tfrom %dth processor: Hello World!\n", rank);

    /* End MPI. */
    MPI_Finalize();

    return 0;
}
컴파일 및 실행
#!syntax sh
$ mpicc a.c
$ mpiexec -n 4 ./a.out
There are total 4 processors.
	from 0th processor: Hello World!
	from 3th processor: Hello World!
	from 1th processor: Hello World!
	from 2th processor: Hello World!


포트란으로 구현한 MPI Hello World! 예제
program main
    use mpi
    implicit none

    integer rank, size, ierr

    ! Start MPI.
    call MPI_INIT(ierr)
    call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
    call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)

    ! Print.
    if (rank == 0) then
        write(*,*) "There are total ", size, " processors."
    endif
    write(*,"(t4,a,i1,a)") "from ", rank, "th processor: Hello World!"
    
    ! End MPI.
    call MPI_FINALIZE(ierr)
end program
컴파일 및 실행
#!syntax sh
$ mpif90 a.f90
$ mpiexec -n 4 ./a.out
 There are total            4  processors.
   from 0th processor: Hello World!
   from 3th processor: Hello World!
   from 1th processor: Hello World!
   from 2th processor: Hello World!

메세지 패싱 인터페이스(Message Passing Interface, MPI)란 병렬 연산 시 프로세서 사이에 메세지를 주고받기 위해 필요한 규칙을 규정한 표준이다. 병렬연산이란 시간이 오래 걸리는 한 큰 연산을 여러개의 프로세서에 나눠서 시키는 전략으로, 각 프로세서가 자기가 어디까지 진도가 나갔는지, 자기가 다른 프로세서로부터 필요한 자료는 무엇이고 줘야 할 자료는 무엇인지 계산을 하면서 지속적으로 정보를 주고 받아야 한다. 이렇게 프로세서간 자료를 주고 받기 위한 통신 표준을 MPI라 한다. 여러 단체들이 이 표준에 맞게 실제로 프로그램을 해 배포하는 여러 배포판이 존재하는데 이 배포판들은 C, 포트란을 지원한다.[1] 대표적으로 쓰이는 MPI 배포판으로는 MPICH, MVAPICH 등이 있다.

1.2. 설명

아무리 수학적으로 간단한 계산이라고 하더라도 크기가 큰 계산은 시간이 오래 걸린다. 예를 들어 행렬 ARn×n\mathbf{A}\in\mathbb{R}^{n\times n}와 벡터 xRn\mathbf{x}\in\mathbb{R}^{n}bRn\mathbf{b}\in\mathbb{R}^{n}가 있을 때
Ax=b\mathbf{A}\mathbf{x}=\mathbf{b}

를 계산하는 것은 고등학교 수학 수준이지만 만약 nn이 엄청나게 큰 경우 아무리 컴퓨터로 계산한다고 하더라고 상상할 수 없을만큼 시간이 오래 걸린다. 예를 들어 nn이 백만이라고 한다면 bib_i을 계산하기 위해서 필요한 aija_{ij}bjb_j 사이의 곱셈이 백만번이고 그렇게 곱한 aijbja_{ij}b_j사이의 덧셈이 99만9999번이다. 이걸 모든 bib_i에 대하여 (백만개) 해야하기 때문에 총 계산 횟수는 (1000000+999999)×10000002×1012(1000000+999999)\times1000000\approx2\times10^{12}번이다. 이 계산을 만약 프로세서 천개에게 나눠 시키면 각 프로세서는 천분의 1만큼의 계산만 하면 되기 때문에 걸리는 시간이 획기적으로 줄 것이다.[2] 이렇게 천개의 프로세서에서 각기 할당량을 나눠주고 계산이 끝났을 때 결과를 받아 이어붙이는 일을 하기 위해서는 프로세서간에 대화가 필요하다. 이 대화를 가능하게 해주는 표준이 MPI이다.

MPI 구간은 MPI_Init에서 시작해서 MPI_Finalize로 끝난다. 이 구간 밖은 같은 코드 안이라도 main processor만 명령을 수행한다.

C 함수들은 모두 시킨 일이 잘 되었는지 안 되었는지를 return 값으로 돌려주며 리턴 값이 없는 포트란 서브루틴들은 서브루틴 제일 끝 parameter로 돌려준다. 즉 C로
int err;
err = MPI_Some_function(a, b, c);
와 포트란으로
integer err
call MPI_Some_function(a, b, c, err)
는 같다.

1.3. MPI를 사용하는 라이브러리

  • PETSc 미국에 있는 Argonne National Lab에서 개발한 선형대수 계산 라이브러리
  • HDF5 The HDF5 Group에서 개발한 I/O 라이브러리
  • ParMETIS 미국 미네소타 주립대(University of Minnesota)에서 개발한 mesh partitioning 라이브러리
  • SuperLU 미국 에너지부(Department of Energy) 산하 연구소인 National Energy Research Scientific Computing Center (NERSC)에서 개발한 super LU decomposition 라이브러리

2. 내연기관 MPI 엔진

파일:상세 내용 아이콘.svg   자세한 내용은 MPI 엔진 문서
번 문단을
부분을
참고하십시오.

3. 일본의 가수

파일:상세 내용 아이콘.svg   자세한 내용은 mpi 문서
번 문단을
부분을
참고하십시오.


[1] 과거에는 C++도 표준에 포함되어 있었으나 MPI 3.0으로 넘어가면서 C++ 바인딩은 표준에서 제외되었다. [2] 천분의 1로 줄지는 않는다. 메세지를 주고 받는 것 자체도 연산이기 때문에 천분의 1보다는 덜 준다. 프로세서의 갯수가 늘어날 수록 대화의 횟수도 늘어나기 때문에 프로세서를 늘리면 늘릴 수록 속도 개선은 점차 저하된다. 이를 오버헤드(overhead)라고 한다.