MPI의 꽃은 MPI_REDUCE가 아닐까?
on
MPI를 써야할 시즌이 다가 오고 있다. 대충 기억을 되살려보면 다음과 같다.
- MPI_Comm_rank: 병렬로 열린 프로세스 중 순번이 몇 번인지 알려준다.
- MPI_Comm_size: 병렬로 열린 프로세스가 몇 개인지 알려준다.
- MPI_Reduce: 일이 끝나면 그것의 총합을 계산한다.
여기에 MPI_AllReduce라는 게 또 있다.
MPI_Reduce와 MPI_AllReduce가 뭐가 다를까 하는 궁금증이 생길 수 있는데, 대충 적어보면 다음과 같다.
- MPI_Reduce는 root process가 개개의 결과를 합산할 때 쓴다.
- MPI_AllReduce는 개개의 process가 개개의 결과의 합산 값을 필요로 할 때 쓴다.
함수 이름과 하는 일의 개념이 다소 차이가 있는 것이 아닐까 생각할 수도 있다. 그러니까 root process가 총합을 계산하는 경우 AllReduce를 써야하는 것이 아닐까 하고 말이다. 어쨌든 그러하다.
인터넷에 올려놓은 예제를 보면 일단 중간 과정에서 개개의 process가 모든 process 결과의 합산값을 필요로 해서 그것을 AllReduce로 얻어내고 다시 그 값을 이용해서 또 다른 결과를 얻어내어 최종적으로 root process에서 총합을 얻어내기 위해 MPI_Reduce를 사용하는 것을 보여준다.
그러니까 MPI의 꽃은 MPI_Reduce이다.
문제는 AllReduce를 사용하든 Reduce를 사용하든 여기서 모든 프로세스의 실행이 완료될 때까지 먼저 일을 끝낸 프로세스들이 그렇지 못한 프로세스들을 기다려야 된다는 것이다. 병렬 작업환경이 훌륭하다면 중간에 약간 쉬어간다고 해서 별 문제는 없다고 볼 수 있다만. 또 어차피 병렬로 하지 않으면 엄청나게 오래 걸릴 일이기 때문에 이쯤 쉰다고 해서 문제될 것은 없지만 일단은 그러하다.
MPI가 나온지는 아주 아주 오래되었지만 C level에서 유용한 함수들을 많이 제공하고 있기 때문에 이것이 C++를 지원하지 않는다고 해도 아쉬울 게 없다. 이를테면 다양한 type이 섞인 struct의 합산을 내야 한다거나 vector가 들어가 있는 struct의 합산을 낸다거나 하는 것은 기본적인 MPI reduce로 할 수 없지만 별도의 call back function을 선언해서 할 수도 있고 또 vector를 쪼개서 MPI reduce를 for loop에 넣고 돌려도 된다.
모든 기능은 다 제공되고 있음에도 이게 안되 저게 안되 불평만 하다보면 쓸 수 있는 기능은 없다.
살아가는 것도 마찬가지 아닐까? 뭐가 되고 싶고, 뭐가 얻고 싶고자 할 때 할 수 있는 가능성의 길은 널려있어도 당장 그게 보이지 않고 어떻게 하는지 알 수 없으니 안된다고 외쳐대면 할 수 있는 것은 아무것도 없는 것 처럼.