이전에 OpenMP를 했고, 이제 MPI를 공부하는데, 사실 어디 가서 병렬계산을 한다고 했을 때, OpenMP나 쿠다는 못해도 병렬계산을 한다고 할 수 있다. 그러나 MPI를 못하면 병렬계산을 한다고 말할 수 없다고 교수님이 그러시더라. 실제로 나도 내 모델링에서 OpenMP나 쿠다는 안써봤는데 MPI는 항상 쓴다.
MPI의 여러 가지 장점을 얘기하자면 다음과 같다.
먼저 universality이다. 쉽게 말해서 어느 아키텍쳐의 컴퓨터에서든 사용 가능하다는 것이다. 슈퍼컴퓨터에서는 당연히 사용 가능하고, 워크스테이션 같은 고성능 공유메모리 컴퓨터나, PC 클러스터와 같은 분산 메모리 환경에서도 모두 사용이 가능하다. 이전에 공부했던 OpenMP는 공유메모리 아키텍쳐에서만 사용이 가능했던 것을 생각하면, universality라는 말이 크게 오바는 아닌 것 같다. 그리고 이러한 universality에서 기인하는 MPI의 특수한 성질이 하나 있는데, datatype이 MPI 전용으로 새롭게 정의된다는 것이다. OpenMP는 한 머신에서만 사용하니까 데이터타입을 새롭게 정의할 필요가 없고 랭귀지에서 정의된 datatype이 그대로 사용된다. 그런데 MPI는 어떤 아키텍쳐의 머신들이 연결되어있을지 모르니까 MPI 전용 datatype이 있는 것이다.
책에 나와있는 다음 장점은 expressivity이다. 여기서 expressivity는 뭐 코드가 예쁘다는 뜻이 아니라, domain decomposition, task parallelism, data decomposition 등의 모든 병렬 패턴을 표현할 수 있다는 것이다. 그리고 OpenMP와 같이 컴파일러가 알아서 병렬화해주는 병렬 모델에서는 없었던 control이 유저에게 있다. 예를 들어서, OpenMP에서는 for loop를 병렬화해달라고 전처리기나 디렉티브만 쓰면 컴파일러가 알아서 스레드에다가 나눠줬는데, 이 경우에 데이터가 어디에 있고 어떤 순서로 계산이 진행되는지를 내가 완전히 통제하기 어렵다. 그러나 MPI에서는 데이터의 위치와 통신과 동기화를 내가 쓰는 표현을 통해 완전히 컨트롤할 수 있다는 것이다. 이게 왜 중요하냐면, 분산 메모리 환경에서는 메모리가 강 노드에 나눠져있다. 그래서 실제 계산 성능은 지금 계산에 사용해야 하는 데이터가 어디에 있냐에 매우 민감하다. MPI에서는 이를 직접 설계할 수 있어서 data locality를 최적화할 수 있다는 것이다. 그런데 사실 이 말은, 프로그래머가 해야 할 게 훨씬 많다는 뜻이기도 하다.
다음 장점은 ease of debugging이다. 병렬 계산에서 가장 주된 에러 원인 중 하나는 unexpected overwriting of memory이다. 그런데 위에서 설명했듯이 MPI에서는 어떤 프로세스가 메모리에 접근해서 읽고 쓸지를 컴파일러가 정하는 것이 아니라 프로그래머가 명시적으로 정하기 때문에 이런 에러를 디버깅하기 쉽다는 것인데, 나한테는 결국 이것도 프로그래머가 할 게 많다는 것으로 들린다.
다음 장점은 performance인데, 결국 속도가 빠르지 않으면 쓸 이유가 없다. 현대 CPU의 연산 속도가 계속 빨라지면서, CPU의 캐시랑 CPU와 정보를 주고받는 메모리를 잘 관리하는 것이 속도를 높이는데 중요하다. MPI는 프로그래머가 특정한 데이터와 프로세스를 명시적으로 연결할 수 있게 해주고, 따라서 컴파일러랑 캐시가 완전하게 기능할 수 있게 해준다. 뭐 뒤에 설명이 더 있긴 한데, 이것도 결국 프로그래머가 고생한다는 얘기이긴 하다.
또 다른 장점은 embarrassingly parallel problem에는 MPI가 완벽하고, OpenMP에서 주된 이슈였던 task 시작과 종료에서 발생하는 overhead가 negligible하다.
이제 단점으로는, 프로그래머가 할 일이 많다는 것이 단점일 수 있고, 노드간의 통신에서 꽤나 큰 overhead가 발생한다는 단점도 있다. 그리고 공유메모리 아키텍쳐에서는 여러 스레드가 여러 작업을 할 때 한 데이터가 공통적으로 필요하더라도 메모리의 정해진 위치에 저장되어있는 데이터를 가져다가 사용하기만 하면 되는데, MPI에서는 여러 노드에서 일을 하다 보니까, 공통적으로 필요한 데이터가 있는 경우에 원래 그 데이터가 있는 노드에서 다른 노드로 복사해와서 그 노드의 메모리에도 데이터를 써놓아야 한다. 즉, 프로세스의 수가 늘어나면 memory cost가 늘어난다는 단점이 있다.