[MPI + CUDA] An Introduction to CUDA-Aware MPI

By | 2016-11-21

Message Passing Interface (MPI)

Message Passing Interface (MPI)는 distributed system에서 데이터 통신을 하기 위한 standard API이다. 주로 High Performance Computing (HPC) 시스템에서 사용된다. 현재 버전의 CUDA는 MPI와 호환이 가능하다고 한다.  MIP+CUDA를 사용하는 이유는 크게 아래와 같다.

  • data size가 너무 커서 하나의 GPU로 실행이 불가능한 경우 (실행은 가능하나 시간이 오래 걸리는 경우)
  • GPU를 사용하여 기존 MPI 프로그램을 가속화 하고 싶은 경우

먼저 MPI에 대한 개념을 정리하였다. MPI 프로그램은 각 메모리 space을 따로 가지고 있다고 한다 (distributed memory space).  결과적으로 cluster 컴퓨터 시스템에서 실행이 가능한 프로그램 형태를 의미한다. 또한, point-to-point 통신을 통하여 프로그램을 실행 할 수 있다고 한다. Reduction과 같은 프로그램도 MPI로 실행이 가능한 이유가 Message passing API를 지원하기 때문이라고 한다. MPI에서는 process를 rank라고 정의한다 (다시 말해서 cluster 0은 rank 0, cluster 1은 rank 1와 같은 형태로 이야기 한다).

ns_attach_image_6261479705477449

그림 1: MPI를 사용하여 hello, there을 프린트 하는 코드 예제 

그림1은 Hello, there을 프린트하는 MPI 프로그램의 코드이다. Rank 0일 경우 message를 rank 1로 보내고, rank 1번은해당 메시지를 받아서 프린트하는 형태이다. 그림 2는 그림 1의 코드를 여러개의 cluster에서 실행되는 그림을 보여준다.

ns_attach_image_6431479705751234

그림 2: MPI 프로그램을 여러개의 cluster에서 실행하는 경우

CUDA-aware MPI

CUDA-aware MPI의 가장 큰 차이점은 GPU 간의 데이터를 전송하는 방법이다. CUDA-aware MPI가 없는 경우 그림 3의 코드와 같이 cudaMemcpy를 사용하여 host memory에 데이터를 복사한 후 다른 cluster에 데이터를 전송한다. 그리고 rank 1은 다시 해당 데이터를 host memory에서 GPU로 복사해야 한다. 반면 CUDA-aware MPI의 경우 host memory에 복사하는 과정이 필요 없다. 그림 4의 코드가 CUDA-aware MPI의 지원하는 경우의 코드이다. 이 경우 cudaMemcpy가 필요 없는 것을 확인할 수 있다.

ns_attach_image_7181479706771058그림 3: Non CUDA-aware MPI (CUDA-aware MPI지원하지 않는 경우)

ns_attach_image_7281479706796470

그림 4: CUDA-aware MPI (CUDA-aware MPI지원하는 경우)

데이터를 복사하는 과정만이 오직 CUDA-aware MPI와 Non CUDA-aware MPI의 차이라고 한다.

ns_attach_image_7411479706951829 (1)

그림 5: Unified Memory Space (UVA)

그림 4와 같이 data를 효과적으로 전송하기 위해서 CUDA는 Unified Memory Space (UVA)를 지원한다. 그림 5는 No UVA와 UVA의 차이를 보여준다. 그림 5의 왼쪽 그림은 UVA를 지원하지 않는 경우이다. 반면 오른쪽 그림은 UVA를 지원하는 경우의 address 영역을 보여준다. 이렇게 UVA를 지원할 경우 MPI는 host memory와 device memory가 virtual address로 연결되어 있어서 MPI에서 따로 데이터를 접근하는데 handling 하는 MPI 함수가 필요 없다고 한다. UVA는 CUDA 4.0부터 지원한다.

CUDA-aware MPI의 장점은 아래와 같이 2개가 있다고 한다.

  • 모든 message transfer가 pipeline 형태로 실행이 가능하다.
  • GPUDirect같은 interconnection을 더 효율적으로 사용할 수 있다.

먼저 GPUDirect에 대해서 정리하였다. GPUDirect는 high-bandwidth, low latency communication 기술을 의미한다. GPUDirect는 다양한 종류의 connection protocol을 지원하는 기술이다.

ns_attach_image_7751479709943894 (1)

그림 6: GPUDirect Peer-To-Peer (P2P) 지원하지 않는 경우와 지원하는 경우의 데이터 복사 방법

그림 6은 GPUDirect Peer-to-Peer (P2P)를 지원하지 않을 때와 지원할 때 GPU 간의 데이터를 복사하는 과정을 보여준다. GPUDirect P2P를 지원하면 GPU memory 간의 데이터 복사가 chip set을 이용하여 바로 가능하다. 반면 GPUDirect P2P를 지원하지 않는 경우는 그림 6 왼쪽 그림처럼 GPU 데이터를 host의 memory에 복사한 후 다시 다른 GPU로 복사해야 한다. 본 기능은 CUDA 4.0부터 지원한다고 한다.

ns_attach_image_7871479710041724 (1)

그림 7: GPUDirect Remote Direct Memory Access (RDMA)를 지원하지 않는 경우와 지원하는 경우의 데이터 복사 방법

그림 7은 GPUDirect Remote Direct Memory Access (RDMA)를 지원하지 않는 경우와 지원하는 경우의 데이터 복사 방법을 보여준다. GPUDirect P2P와 비슷한 복사방법이다. 이 방법은 GPU의 데이터를 다른 클러스터로 보내는 방법을 의미한다. GPUDirect RDMA를 지원하지 않는 경우 GPU의 데이터가 host memory에 복사한 후 다른 cluster로 데이터가 복사된다. 반면  GPUDirect RDMA를 지원하는 경우 오른쪽 그림과 같이 바로 다른 cluster로 데이터 복사가 가능하다.

아래 그림들은 Non CUDA-aware MPI의 데이터 복사 순서와 CUDA-aware MPI + GPUDirect를 사용하였을 때의 데이터 복사 순서를 정리한 그림이다.

ns_attach_image_8221479710282363그림 8: 데이터 복사 순서를 설명하기 위한 그림 설명

ns_attach_image_8021479710267582 (1)

그림 9: Non CUDA-aware MPI의 데이터 복사 순서

ns_attach_image_8111479710272040 (1)

그림 10: Non CUDA-aware MPI의 데이터 복사 순서 시간

그림9, 그림 10는  CUDA-aware MPI를 지원하지 않는 경우의 데이터 복사 순서를 나열한 그림이다 (그림 7에 각 블록의 의미가 정리되어있다) . 위 그림들과 같이 먼저 GPU의 데이터를 GPU memory에서 host memory로 복사한다. 복사가 완료되면 다시 host memory에서 Fabric buffer로 복사하게 된다. Fabric buffer는 host memory에 있다고 한다. Fabric buffer에 복사된 데이터는 순차적으로 다른 cluster의 Fabric buffer로 복사되게 된다. Fabric buffer로 복사가 완료된 후 cluster의 memory에 다시 한 번 데이터 복사를 진행한다. 마지막으로 해당 cluster의 memory에서 GPU memory로 데이터를 복사하면 모든 데이터 복사가 완료된다. 다른 cluster에 설치된 GPU 간의 데이터 복사를 위해 상당히 많은 overhead가 존재한다.

ns_attach_image_8341479710420830

그림 11: CUDA-aware MPI + Non GPUDirect의 데이터 복사 순서

ns_attach_image_8431479710424935

그림 12: CUDA-aware MPI + Non GPUDirect의 데이터 복사 순서 시간

그림 11, 그림 12은 CUDA-aware MPI를 지원하지만 GPUDirect를 지원하지 않는 경우의 데이터 복사를 표현한 그림이다. Non CUDA-aware MPI와 달리 이 경우는 host memory로 복사하는 시간이 필요 없다. 단순히 host memory에서 바로 Fabric buffer로 복사를 진행하고 그 데이터를 순차적으로 다른 cluster의 Fabric buffer로 전송된다. Fabric buffer의 데이터는 또한 순차적으로 GPU memory로 못하게 된다. 결과적으로 Non CUDA-aware MPI보다 따른 성능을 보인다. 모른 복사 step이 파이프라인화 되어서 latency hiding이 가능하다고 한다.

ns_attach_image_8631479710547720

그림 13: CUDA-aware MPI + GPUDirect의 데이터 복사 순서

ns_attach_image_8721479710552909

그림 14: CUDA-aware MPI + GPUDirect의 데이터 복사 순서 시간

마지막으로 CUDA-aware MPI와 GPUDirect를 지원하는 경우이다. 그림 13와 14은 CUDA-aware MPI+GPUDirect를 지원하는 경우이다.  GPUDirect를 지원하지 않는 경우와 달리 GPU에서 다른 cluster의 GPU로 바로 데이터 전송이 가능하다. 간단하게 network의 overhead만 존재한다.

MPI+CUDA에 큰 관심이 없다. 하지만 연구실에서 MPI+CUDA에 관련된 발표 자료를 만들면서 읽은 부분을 정리하였다.

출처

  1. https://devblogs.nvidia.com/parallelforall/introduction-cuda-aware-mpi/

Leave a Reply

Your email address will not be published. Required fields are marked *