Main Content

GPU 성능 측정 및 개선하기

GPU 성능 측정하기

GPU에서 코드 성능 측정하기

코드의 성능에 대한 중요한 척도는 실행하는 데 걸리는 시간입니다. GPU에서 실행 중인 코드의 시간을 측정하는 가장 좋은 방법은, 함수를 여러 번 실행하여 변동에 대한 평균을 구하고 오버헤드를 보정하는 gputimeit 함수를 사용하는 것입니다. gputimeit 함수는 또한 시간을 기록하기 전에 모든 GPU 연산이 완료되도록 합니다.

예를 들어, lu 함수가 크기가 N×N인 확률 행렬 A의 LU 분해를 계산하는 데 걸리는 시간을 측정해 보겠습니다. 이러한 측정을 수행하기 위해 lu 함수에 대한 함수 핸들을 만들고 이 함수 핸들을 gputimeit로 전달합니다.

N = 1000;
A = rand(N,"gpuArray");
f = @() lu(A);
numOutputs = 2;
gputimeit(f,numOutputs)

또한 tictoc를 사용하여 코드의 시간을 측정할 수 있습니다. 그러나 GPU에서 실행 중인 코드에 대한 정확한 시간 측정 정보를 얻으려면 tictoc를 호출하기 전에 연산이 완료될 때까지 기다려야 합니다. 이 작업을 수행하기 위해 gpuDevice 객체를 입력값으로 하는 wait 함수를 사용할 수 있습니다. 예를 들어, tic, toc, wait를 사용하여 행렬 A의 LU 분해를 계산하는 데 걸리는 시간을 측정해 보겠습니다.

D = gpuDevice;
wait(D)
tic
[L,U] = lu(A);
wait(D)
toc

MATLAB® 프로파일러를 사용하여 코드의 각 부분에서 걸리는 시간을 볼 수 있습니다. 코드 프로파일링에 대한 자세한 내용은 profile 항목과 코드를 프로파일링하여 성능 개선하기 항목을 참조하십시오. 프로파일러는 코드의 성능 병목 현상을 식별하는 데 유용하지만 GPU 사용 시 흔히 발생하는 중첩 실행을 고려하지 않기 때문에 GPU 코드의 시간을 정확하게 측정할 수 없습니다.

사용할 시간 측정 방법을 결정해야 할 때 다음 표를 참조하십시오.

시간 측정 방법적합한 작업제한 사항
gputimeit개별 함수의 시간 측정
  • gputimeit 함수는 함수 핸들이 인수로 필요하므로 단일 함수의 시간을 측정할 때만 이 방법을 사용할 수 있습니다. 그러나 시간을 측정하는 함수가 다른 함수에 대한 호출을 포함할 수 있습니다.

  • gputimeit 함수는 초기화 오버헤드를 고려하여 함수를 여러 번 실행하므로 장시간 실행되는 함수의 시간 측정에는 대체로 이 방법이 적합하지 않습니다.

tictoc코드의 여러 라인 또는 전체 워크플로의 시간 측정
  • 모든 GPU 연산이 완료되도록 하려면 toc를 호출하기 전에 wait를 호출해야 합니다. 마찬가지로, 이전 코드가 GPU에서 실행되는 경우 tic를 호출하기 전에 wait를 호출해야 합니다.

  • gputimeit의 실행 시간을 측정하기 위해 tictoc를 사용할 수 없습니다.

MATLAB 프로파일러성능 병목 현상 찾기

프로파일러는 각 코드 라인을 독립적으로 실행하며 GPU 사용 시 흔히 발생하는 중첩 실행을 고려하지 않습니다. 프로파일러를 GPU 코드의 시간을 정확하게 측정하기 위한 방법으로 사용할 수는 없습니다.

GPU 벤치마킹

벤치마크 테스트는 GPU의 장단점을 식별하고 다양한 GPU의 성능을 비교하는 데 유용합니다. 다음과 같은 벤치마크 테스트를 사용하여 GPU 성능을 측정하십시오.

  • Measure GPU Performance 예제를 실행하여 PCI 버스 속도, GPU 메모리 읽기/쓰기, 배정밀도 행렬 계산의 피크 계산 성능을 포함한 GPU에 대한 자세한 정보를 얻습니다.

  • gpuBench를 사용하여 메모리를 많이 사용하는 작업과 계산량이 많은 작업을 단정밀도와 배정밀도로 테스트합니다. gpuBench는 애드온 탐색기 또는 MATLAB Central File Exchange에서 다운로드할 수 있습니다. 자세한 내용은 https://www.mathworks.com/matlabcentral/fileexchange/34080-gpubench 항목을 참조하십시오.

GPU 성능 개선하기

MATLAB에서 GPU 연산의 목적은 코드의 속도를 높이는 데 있습니다. 코드 작성과 GPU 하드웨어 구성에 대한 모범 사례를 구현하여 GPU에서 더 나은 성능을 달성할 수 있습니다. 성능 개선을 위한 다양한 방법이 가장 간단하게 구현할 수 있는 방법부터 아래에 설명되어 있습니다.

사용할 방법을 결정해야 할 때 이 표를 참조하십시오.

성능 개선 방법해당 방법을 사용할 수 있는 경우제한 사항

GPU 배열 사용하기 – GPU 배열을 지원되는 함수로 전달하여 GPU에서 코드를 실행합니다.

일반적으로 적용 가능

함수가 gpuArray 입력값을 지원해야 합니다. gpuArray 입력값을 지원하는 MATLAB 함수의 목록은 GPU에서 MATLAB 함수 실행하기 항목을 참조하십시오.

MATLAB 코드 프로파일링 및 개선하기 – 코드를 프로파일링하여 병목 현상을 식별합니다.

일반적으로 적용 가능

프로파일러는 GPU에서 코드 성능 측정하기 섹션에 설명된 대로 GPU에서 실행 중인 코드의 시간을 정확하게 측정하는 데 사용할 수 없습니다.

계산 벡터화하기 – for 루프를 행렬 연산과 벡터 연산으로 바꿉니다.

for 루프 내 벡터 또는 행렬에서 동작하는 코드를 실행하는 경우

자세한 내용은 벡터화 사용 항목을 참조하십시오.

단정밀도로 계산 수행하기 – 정밀도가 낮은 데이터를 사용하여 계산량을 줄입니다.

더 작은 범위의 값과 더 낮은 정확도가 허용되는 경우

선형 대수 문제와 같은 일부 유형의 계산은 배정밀도 처리가 필요할 수 있습니다.

arrayfun 사용 – 사용자 지정 CUDA® 커널을 사용하여 요소별 함수를 실행합니다.

  • 다수의 요소별 연산을 수행하는 함수를 사용하는 경우

  • 중첩 함수가 해당 부모 함수에 선언된 변수에 액세스해야 하는 경우

  • 입력 배열이나 출력 배열의 크기나 형태를 변경하는 연산(cat, reshape 등)은 지원되지 않습니다.

  • 일부 내장 MATLAB 함수는 지원되지 않습니다.

지원되는 함수와 추가 제한 사항에 대한 자세한 내용은 arrayfun 항목을 참조하십시오.

pagefun 사용 – 행렬 연산을 여러 배치로 나눈 것을 단일 호출로 수행합니다.

다수의 작은 행렬에 대해 독립적인 행렬 연산을 수행하는 함수를 사용하는 경우

일부 내장 MATLAB 함수는 지원되지 않습니다. 지원되는 함수와 추가 제한 사항에 대한 자세한 내용은 pagefun 항목을 참조하십시오.

CUDA 코드가 포함된 MEX 파일 작성하기 – GPU 함수의 추가 라이브러리에 액세스합니다.

NVIDIA® 라이브러리 또는 고급 CUDA 기능에 액세스하려는 경우CUDA C++ 프레임워크를 사용하여 작성된 코드가 필요합니다.

GPU 성능을 위해 하드웨어 구성하기 – 하드웨어를 최대한 활용합니다.

일반적으로 적용 가능
  • 일부 NVIDIA GPU 장치는 TCC 모드를 지원하지 않습니다.

  • TCC 모드에서 GPU 장치는 계산에만 사용되며 디스플레이 출력은 제공하지 않습니다.

GPU 배열 사용하기

코드에서 사용하는 모든 함수가 GPU에서 지원되는 경우, 필요한 수정 작업은 gpuArray를 호출하여 입력 데이터를 GPU로 전송하는 것뿐입니다. gpuArray 입력값을 지원하는 MATLAB 함수의 목록은 GPU에서 MATLAB 함수 실행하기 항목을 참조하십시오.

gpuArray 객체는 데이터를 GPU 메모리에 저장합니다. MATLAB과 기타 여러 툴박스에 있는 대부분의 숫자형 함수가 gpuArray 객체를 지원하므로 대개 최소한의 변경으로 GPU에서 코드를 실행할 수 있습니다. 이러한 함수는 gpuArray 입력값을 받고 GPU에서 계산을 수행한 후 gpuArray 출력값을 반환합니다. 일반적으로 이러한 함수는 CPU에서 실행되는 표준 MATLAB 함수와 동일한 인수 및 데이터형을 지원합니다.

오버헤드를 줄이려면 호스트 메모리와 GPU 간에 데이터를 전송하는 횟수를 제한하십시오. 가능한 경우 배열을 GPU에서 직접 배열을 만드십시오. 자세한 내용은 GPU 배열 직접 만들기 항목을 참조하십시오. 마찬가지로, gpuArray 객체를 지원하지 않는 코드에서 데이터를 표시, 저장 또는 사용해야 하는 경우에만 gather를 사용하여 데이터를 GPU에서 호스트 메모리로 다시 전송하십시오.

MATLAB 코드 프로파일링 및 개선하기

MATLAB 코드를 GPU에서 실행되도록 변환할 때는 이미 잘 수행되는 MATLAB 코드부터 시작하는 것이 가장 좋습니다. 또한 CPU에서 잘 실행되는 코드 작성에 대한 여러 가지 지침을 토대로 GPU에서 실행되는 코드의 성능을 개선할 수도 있습니다. MATLAB 프로파일러를 사용하여 CPU 코드를 프로파일링할 수 있습니다. CPU에서 가장 많은 시간이 걸리는 코드 라인은 개선해야 하거나 gpuArray 객체를 사용하여 GPU로 이동시켜야 하는 코드 라인일 가능성이 큽니다. 코드 프로파일링에 대한 자세한 내용은 코드를 프로파일링하여 성능 개선하기 항목을 참조하십시오.

MATLAB 프로파일러는 각 코드 라인을 독립적으로 실행하기 때문에 GPU 사용 시 흔히 발생하는 중첩 실행을 고려하지 않습니다. 전체 알고리즘의 시간을 측정하려면 GPU에서 코드 성능 측정하기 섹션에 설명된 대로 tictoc 또는 gputimeit를 사용하십시오.

계산 벡터화하기

GPU에서는 일반적으로 벡터 연산, 행렬 연산, 더 높은 차원의 연산이 스칼라 연산보다 훨씬 더 잘 수행됩니다. 왜냐하면 많은 결과값을 병렬로 계산함으로써 GPU에서 높은 성능을 얻을 수 있기 때문입니다. 더 높은 차원의 연산을 활용하도록 루프를 재작성하면 더 나은 성능을 얻을 수 있습니다. MATLAB 행렬과 벡터 연산을 사용하도록 루프 기반의, 스칼라 위주의 코드를 수정하는 과정을 벡터화라고 합니다. 벡터화에 대한 자세한 내용은 벡터화 사용 항목과 Improve Performance Using a GPU and Vectorized Calculations 항목을 참조하십시오. Improve Performance Using a GPU and Vectorized Calculations 예제에서 발췌한 다음 플롯은 CPU와 GPU에서 실행되는 함수를 벡터화함으로써 얻을 수 있는 성능 개선을 보여줍니다.

Bar chart showing a significant reduction in function execution time by vectorizing calculations, for both CPU and GPU execution.

단정밀도로 계산 수행하기

배정밀도 대신 단정밀도로 계산을 수행하여 GPU에서 실행되는 코드의 성능을 개선할 수 있습니다. CPU 연산에서는 배정밀도에서 단정밀도로 전환하는 경우 이러한 성능 개선 효과를 얻을 수 없습니다. 대부분의 GPU 카드는 높은 단정밀도 성능이 필요한 그래픽 디스플레이용으로 설계되었기 때문입니다. 데이터를 단정밀도로 변환하고 단정밀도 데이터에 대해 산술 연산을 수행하는 방법에 대한 자세한 내용은 부동소수점 숫자(Floating-Point Number) 항목을 참조하십시오.

GPU에서 단정밀도 계산에 적합한 워크플로의 일반적인 예로는 영상 처리 및 머신러닝이 있습니다. 그러나 선형 대수 문제와 같은 기타 유형의 계산에는 일반적으로 배정밀도 처리가 필요합니다. Deep Learning Toolbox™는 기본적으로 단정밀도로 많은 연산을 수행합니다. 자세한 내용은 Deep Learning Precision (Deep Learning Toolbox) 항목을 참조하십시오.

정확한 성능 개선은 GPU 카드와 총 코어 수에 따라 달라집니다. 고급 계산 카드는 일반적으로 성능 개선 효과가 이보다 적습니다. 단정밀도 처리 성능과 배정밀도 처리 성능을 비롯한 NVIDIA GPU 카드의 종합적인 성능 개요는 https://en.wikipedia.org/wiki/List_of_Nvidia_graphics_processing_units 항목을 참조하십시오.

요소별 함수의 성능 개선하기

요소별 함수가 있는 경우, 대개 arrayfun을 사용하여 이 함수를 호출하면 성능을 개선할 수 있습니다. GPU에서 arrayfun 함수는 요소별 MATLAB 함수를 사용자 지정 CUDA 커널로 전환하므로 연산 수행에 대한 오버헤드가 줄어듭니다. arrayfun이 전체 코드를 지원하지 않는 경우에도 보통은 코드의 일부에 arrayfun을 사용할 수 있습니다. 루프 또는 분기 코드 내에서 다수의 요소별 연산을 수행하는 함수와 중첩 함수(즉, 부모 함수에 선언된 변수에 액세스하는 중첩 함수)를 포함한 다양한 요소별 함수의 성능은 arrayfun을 사용하여 개선할 수 있습니다.

Improve Performance of Element-Wise MATLAB Functions on the GPU Using arrayfun 예제에서는 arrayfun의 기본적인 응용을 보여줍니다. Using GPU arrayfun for Monte-Carlo Simulations 예제에서는 루프 내에서 요소별 연산을 실행 중인 함수의 성능을 개선하기 위해 사용되는 arrayfun을 보여줍니다. Stencil Operations on a GPU 예제에서는 부모 함수에 선언된 변수에 액세스하는 중첩 함수를 호출하기 위해 사용되는 arrayfun을 보여줍니다.

소규모 행렬의 연산 성능 개선하기

다수의 소규모 행렬에 대해 독립적인 행렬 연산을 수행하는 함수가 있는 경우 pagefun으로 이 함수를 호출하면 성능을 개선할 수 있습니다. 행렬을 루핑하는 대신 pagefun을 사용하여 GPU에서 행렬 연산을 병렬로 수행할 수 있습니다. Improve Performance of Small Matrix Problems on the GPU Using pagefun 예제에서는 다수의 소규모 행렬에 대해 연산을 수행할 때 pagefun을 사용하여 성능을 개선하는 방법을 보여줍니다.

CUDA 코드가 포함된 MEX 파일 작성하기

MATLAB은 광범위한 GPU 지원 함수 라이브러리를 제공하는 한편, 유사성이 없는 추가적인 함수 라이브러리에 대한 액세스도 MATLAB에서 제공하고 있습니다. 그 예로는 NPP(NVIDIA Performance Primitives), cuRAND 라이브러리와 같은 NVIDIA 라이브러리가 있습니다. mexcuda 함수를 사용하여 CUDA C++ 프레임워크로 작성한 MEX 파일을 컴파일할 수 있습니다. 컴파일된 MEX 파일을 MATLAB에서 실행하고 NVIDIA 라이브러리의 함수를 호출할 수 있습니다. gpuArray 입력값을 받고 gpuArray 출력값을 반환하는 MEX 함수를 작성하고 실행하는 방법을 보여주는 예제는 CUDA 코드가 포함된 MEX 함수 실행 항목을 참조하십시오.

GPU 성능을 위해 하드웨어 구성하기

계산에 대량의 메모리가 필요한 경우가 많고 대부분의 시스템은 그래픽에 GPU를 지속적으로 사용하기 때문에 계산과 그래픽에 동일한 GPU를 사용하는 것은 일반적으로 적절하지 않습니다.

Windows® 시스템에서 GPU 장치는 두 가지 운영 모델이 있습니다. 바로 WDDM(Windows Display Driver Model)과 TCC(Tesla Compute Cluster)입니다. 코드와 관련해 최상의 성능을 얻으려면 계산에 사용하는 장치가 TCC 모델을 사용하도록 설정하십시오. GPU 장치에서 현재 어떤 모델을 사용 중인지 확인하려면 gpuDevice 함수가 반환하는 DriverModel 속성을 살펴봅니다. 모델 전환과 TCC 모델을 지원하는 GPU 장치에 대한 자세한 내용은 NVIDIA 문서를 참조하십시오.

GPU에서 메모리 부족 가능성을 줄이려면 MATLAB의 여러 인스턴스에 하나의 GPU를 사용하지 마십시오. 어떤 GPU 장치가 사용 가능하고 선택되어 있는지 확인하려면 gpuDeviceTable 함수를 사용합니다.

참고 항목

| | | | | | |

관련 항목