CUDA는 무엇입니까? GPU를위한 병렬 프로그래밍

CUDA는 Nvidia가 자체 GPU (그래픽 처리 장치)에서 일반 컴퓨팅을 위해 개발 한 병렬 컴퓨팅 플랫폼 및 프로그래밍 모델입니다. CUDA를 통해 개발자는 컴퓨팅의 병렬화 가능한 부분에 GPU의 성능을 활용하여 컴퓨팅 집약적 인 애플리케이션의 속도를 높일 수 있습니다.

OpenCL과 같은 GPU 용으로 제안 된 다른 API가 있고 AMD와 같은 다른 회사의 경쟁 GPU가 있지만 CUDA와 Nvidia GPU의 조합은 딥 러닝을 포함한 여러 응용 분야를 지배하며 일부의 기초가됩니다. 세계에서 가장 빠른 컴퓨터.

그래픽 카드는 PC만큼 오래되었습니다. 즉, 1981 년 IBM Monochrome Display Adapter를 그래픽 카드라고 생각한다면 말입니다. 1988 년까지 ATI (이 회사는 결국 AMD에 인수 됨)에서 16 비트 2D VGA Wonder 카드를 얻을 수 있습니다. 1996 년까지 3dfx Interactive에서 3D 그래픽 가속기를 구입하여 1 인칭 슈팅 게임 인 Quake를 최고 속도로 실행할 수 있습니다.

또한 1996 년 엔비디아는 약한 제품으로 3D 가속기 시장에서 경쟁하기 시작했지만 그 과정에서 배웠고 1999 년 GPU라고 불리는 최초의 그래픽 카드 인 성공적인 지포스 256을 출시했습니다. 당시 GPU가있는 주된 이유는 게임이었습니다. 사람들이 수학, 과학 및 공학에 GPU를 사용한 것은 나중에 야합니다.

CUDA의 기원

2003 년 Ian Buck이 이끄는 연구팀은 데이터 병렬 구조로 C를 확장하기 위해 처음으로 널리 채택 된 프로그래밍 모델 인 Brook을 공개했습니다. Buck은 나중에 Nvidia에 합류하여 2006 년 GPU에서 범용 컴퓨팅을위한 최초의 상용 솔루션 인 CUDA 출시를 이끌었습니다.

OpenCL 대 CUDA

CUDA 경쟁 업체 인 OpenCL은 Nvidia GPU를 사용하는 Intel / AMD CPU에 국한되지 않는 이기종 컴퓨팅 표준을 제공하기 위해 2009 년 Apple과 Khronos Group에서 출시했습니다. OpenCL은 일반성으로 인해 매력적으로 들리지만 Nvidia GPU에서 CUDA만큼 잘 수행되지 않았으며 많은 딥 러닝 프레임 워크가 CUDA 지원이 출시 된 후에 만 ​​지원하거나 지원하지 않습니다.

CUDA 성능 향상

CUDA는 개선 된 Nvidia GPU를 사용하여 수년에 걸쳐 범위를 개선하고 확장했습니다. CUDA 버전 9.2부터는 다중 P100 서버 GPU를 사용하여 CPU보다 최대 50 배 향상된 성능을 실현할 수 있습니다. V100 (이 그림에 표시되지 않음)은 일부 부하에서 또 다른 3 배 더 빠릅니다. 이전 세대의 서버 GPU 인 K80은 CPU보다 5 배에서 12 배 향상된 성능을 제공했습니다.

엔비디아

GPU의 속도 향상은 고성능 컴퓨팅의 시대에 접어 들었습니다. 시간이 지남에 따라 CPU의 단일 스레드 성능 향상 (무어의 법칙이 18 개월마다 두 배로 제안)은 칩 제조업체가 제조 공정 중 칩 마스크 해상도 및 칩 수율에 대한 크기 제한을 포함한 물리적 한계에 직면함에 따라 연간 10 %로 느려졌습니다. 그리고 런타임에 클럭 주파수에 대한 열 제한.

엔비디아

CUDA 애플리케이션 도메인

엔비디아

CUDA 및 Nvidia GPU는 위 이미지에 그림으로 요약 된 것처럼 높은 부동 소수점 컴퓨팅 성능이 필요한 많은 영역에서 채택되었습니다. 보다 포괄적 인 목록은 다음과 같습니다.

  1. 전산 금융
  2. 기후, 날씨 및 해양 모델링
  3. 데이터 과학 및 분석
  4. 딥 러닝과 머신 러닝
  5. 국방 및 정보
  6. 제조 / AEC (건축, 엔지니어링 및 건설) : CAD 및 CAE (전산 유체 역학, 전산 구조 역학, 설계 및 시각화, 전자 설계 자동화 포함)
  7. 미디어 및 엔터테인먼트 (애니메이션, 모델링 및 렌더링 포함, 색상 보정 및 그레인 관리, 합성, 마무리 및 효과, 편집, 인코딩 및 디지털 배포, 온에어 그래픽, 온셋, 리뷰 및 스테레오 도구, 날씨 그래픽)
  8. 의료 영상
  9. 석유와 가스
  10. 연구 : 고등 교육 및 슈퍼 컴퓨팅 (전산 화학 및 생물학, 수치 분석, 물리학 및 과학 시각화 포함)
  11. 안전과 보안
  12. 도구 및 관리

딥 러닝의 CUDA

딥 러닝은 컴퓨팅 속도에 대한 요구가 매우 높습니다. 예를 들어, 2016 년에 Google 번역 용 모델을 교육하기 위해 Google Brain 및 Google 번역 팀은 GPU를 사용하여 1 주일에 걸쳐 수백 번의 TensorFlow 실행을 수행했습니다. 그들은 목적을 위해 Nvidia에서 2,000 개의 서버급 GPU를 구입했습니다. GPU가 없었다면 이러한 훈련 실행은 수렴하는 데 일주일이 아니라 몇 달이 걸렸을 것입니다. 이러한 TensorFlow 번역 모델의 프로덕션 배포를 위해 Google은 새로운 커스텀 처리 칩인 TPU (텐서 처리 장치)를 사용했습니다.

TensorFlow 외에도 Caffe2, CNTK, Databricks, H2O.ai, Keras, MXNet, PyTorch, Theano 및 Torch를 포함한 많은 다른 DL 프레임 워크가 GPU 지원을 위해 CUDA에 의존합니다. 대부분의 경우 심층 신경망 계산을 위해 cuDNN 라이브러리를 사용합니다. 이 라이브러리는 딥 러닝 프레임 워크의 학습에 매우 중요하므로 주어진 버전의 cuDNN을 사용하는 모든 프레임 워크는 동일한 사용 사례에 대해 본질적으로 동일한 성능 수치를 갖습니다. CUDA 및 cuDNN이 버전마다 개선되면 새 버전으로 업데이트되는 모든 딥 러닝 프레임 워크가 성능 향상을 확인합니다. 프레임 워크마다 성능이 다른 경향은 여러 GPU 및 여러 노드로 얼마나 잘 확장되는지에 있습니다.

CUDA 프로그래밍

엔비디아

CUDA 툴킷

CUDA Toolkit에는 라이브러리, 디버깅 및 최적화 도구, 컴파일러, 문서, 애플리케이션 배포를위한 런타임 라이브러리가 포함되어 있습니다. 딥 러닝, 선형 대수, 신호 처리 및 병렬 알고리즘을 지원하는 구성 요소가 있습니다. 일반적으로 CUDA 라이브러리는 모든 Nvidia GPU 제품군을 지원하지만 V100과 같은 최신 세대에서 최고의 성능을 발휘합니다. V100은 딥 러닝 훈련 워크로드의 경우 P100보다 3 배 빠릅니다. 필요한 알고리즘이 적절한 라이브러리에 구현되어있는 한 하나 이상의 라이브러리를 사용하는 것이 GPU를 활용하는 가장 쉬운 방법입니다.

엔비디아

CUDA 딥 러닝 라이브러리

딥 러닝 영역에는 GPU 가속 라이브러리 세 가지가 있습니다. 이전에 대부분의 오픈 소스 딥 러닝 프레임 워크의 GPU 구성 요소로 언급 한 cuDNN; Nvidia의 고성능 딥 러닝 추론 최적화 프로그램 및 런타임 인 ​​TensorRT 비디오 추론 라이브러리 인 DeepStream이 있습니다. TensorRT는 신경망 모델을 최적화하고 높은 정확도로 낮은 정밀도로 보정하며 훈련 된 모델을 클라우드, 데이터 센터, 임베디드 시스템 또는 자동차 제품 플랫폼에 배포하는 데 도움이됩니다.

엔비디아

CUDA 선형 대수 및 수학 라이브러리

선형 대수는 텐서 계산과 딥 러닝을 뒷받침합니다. 1989 년 Fortran에서 구현 된 매트릭스 알고리즘 모음 인 BLAS (Basic Linear Algebra Subprograms)는 그 이후로 과학자와 엔지니어가 사용해 왔습니다. cuBLAS는 BLAS의 GPU 가속 버전이며 GPU로 행렬 산술을 수행하는 고성능 방법입니다. cuBLAS는 행렬이 조밀하다고 가정합니다. cuSPARSE는 희소 행렬을 처리합니다.

엔비디아

CUDA 신호 처리 라이브러리

고속 푸리에 변환 (FFT)은 신호 처리에 사용되는 기본 알고리즘 중 하나입니다. 신호 (예 : 오디오 파형)를 주파수 스펙트럼으로 변환합니다. cuFFT는 GPU 가속 FFT입니다.

H.264와 같은 표준을 사용하는 코덱은 전송 및 표시를 위해 비디오를 인코딩 / 압축 및 디코딩 / 압축 해제합니다. Nvidia Video Codec SDK는 GPU를 통해이 프로세스의 속도를 높입니다.

엔비디아

CUDA 병렬 알고리즘 라이브러리

병렬 알고리즘을위한 세 가지 라이브러리는 모두 다른 목적을 가지고 있습니다. NCCL (Nvidia Collective Communications Library)은 여러 GPU 및 노드에서 앱을 확장하기위한 것입니다. nvGRAPH는 병렬 그래프 분석 용입니다. Thrust는 C ++ 표준 템플릿 라이브러리를 기반으로하는 CUDA 용 C ++ 템플릿 라이브러리입니다. Thrust는 스캔, 정렬 및 축소와 같은 다양한 데이터 병렬 기본 요소 모음을 제공합니다.

엔비디아

CUDA 대 CPU 성능

경우에 따라 동등한 CPU 기능 대신 드롭 인 CUDA 기능을 사용할 수 있습니다. 예를 들어 BLAS의 GEMM 행렬 곱셈 루틴은 NVBLAS 라이브러리에 연결하기 만하면 GPU 버전으로 대체 될 수 있습니다.

엔비디아

CUDA 프로그래밍 기본 사항

프로그램을 가속화하는 CUDA 라이브러리 루틴을 찾을 수 없다면 저수준 CUDA 프로그래밍을 시도해야합니다. 2000 년대 후반에 처음 시도했을 때보 다 훨씬 쉬워졌습니다. 다른 이유 중에서도 더 쉬운 구문이 있고 더 나은 개발 도구를 사용할 수 있습니다. 내 유일한 문제는 MacOS에서 최신 CUDA 컴파일러와 최신 C ++ 컴파일러 (Xcode의)가 거의 동기화되지 않는다는 것입니다. Apple에서 이전 명령 줄 도구를 다운로드하고이를 사용 xcode-select하여 CUDA 코드를 컴파일하고 링크하도록 전환해야합니다 .

예를 들어, 다음 두 개의 배열을 추가하는 간단한 C / C ++ 루틴을 고려하십시오.

void add (int n, float * x, float * y)

{  

       for (int i = 0; i <n; i ++)      

             y [i] = x [i] + y [i];

}

__global__선언에 키워드를 추가하여 GPU에서 실행할 커널로 전환 하고 삼중 대괄호 구문을 사용하여 커널을 호출 할 수 있습니다.

add << >> (N, x, y);

또한 변경해야 malloc/ newfree/ delete호출을 cudaMallocManaged하고 cudaFree그래서 당신이 GPU에 공간을 할당됩니다. 마지막으로 CPU에서 결과를 사용하기 전에 GPU 계산이 완료 될 때까지 기다려야합니다 cudaDeviceSynchronize.

위의 트리플 브래킷은 하나의 스레드 블록과 하나의 스레드를 사용합니다. 현재 Nvidia GPU는 많은 블록과 스레드를 처리 할 수 ​​있습니다. 예를 들어, Pascal GPU 아키텍처를 기반으로하는 Tesla P100 GPU에는 각각 최대 2048 개의 활성 스레드를 지원할 수있는 56 개의 SM (Streaming Multiprocessor)이 있습니다.

커널 코드는 전달 된 배열에서 오프셋을 찾기 위해 블록과 스레드 인덱스를 알아야합니다. 병렬화 된 커널은 종종 다음과 같은 그리드-스트라이드 루프를 사용합니다 .

__global__

void add (int n, float * x, float * y)

{

   int 인덱스 = blockIdx.x * blockDim.x + threadIdx.x;

   int stride = blockDim.x * gridDim.x;

   for (int i = index; i <n; i + = stride)

     y [i] = x [i] + y [i];

}

CUDA 툴킷의 샘플을 보면 위에서 다룬 기본 사항보다 고려해야 할 사항이 더 많다는 것을 알 수 있습니다. 예를 들어, 일부 CUDA 함수 호출은 checkCudaErrors()호출 로 래핑되어야 합니다. 또한 대부분의 경우 가장 빠른 코드는 cuBLAS호스트 및 장치 메모리 할당 및 행렬 복사와 같은 라이브러리를 사용 합니다.

요약하면 여러 수준에서 GPU를 사용하여 앱을 가속화 할 수 있습니다. CUDA 코드를 작성할 수 있습니다. CUDA 라이브러리를 호출 할 수 있습니다. 이미 CUDA를 지원하는 애플리케이션을 사용할 수 있습니다.