MATLAB이 행렬 곱셈에서 왜 그렇게 빠릅니까?


190

CUDA, C ++, C #, Java로 벤치 마크를하고 확인 및 매트릭스 생성을 위해 MATLAB을 사용하고 있습니다. MATLAB을 사용하여 행렬 곱셈을 수행하면 2048x2048더 큰 행렬도 거의 즉시 곱해집니다.

             1024x1024   2048x2048   4096x4096
             ---------   ---------   ---------
CUDA C (ms)      43.11      391.05     3407.99
C++ (ms)       6137.10    64369.29   551390.93
C# (ms)       10509.00   300684.00  2527250.00
Java (ms)      9149.90    92562.28   838357.94
MATLAB (ms)      75.01      423.10     3133.90

CUDA만이 경쟁력이 있지만 적어도 C ++은 다소 가깝고 60 배 느리지 않을 것이라고 생각했습니다. 또한 C # 결과에 대해 어떻게 생각해야할지 모르겠습니다. 이 알고리즘은 C ++ 및 Java와 동일하지만 2048에서 크게 발전 했습니다 1024.

MATLAB은 어떻게 행렬 곱셈을 그렇게 빨리 수행합니까?

C ++ 코드 :

float temp = 0;
timer.start();
for(int j = 0; j < rozmer; j++)
{
    for (int k = 0; k < rozmer; k++)
    {
        temp = 0;
        for (int m = 0; m < rozmer; m++)
        {
            temp = temp + matice1[j][m] * matice2[m][k];
        }
        matice3[j][k] = temp;
    }
}
timer.stop();

14
아마도 어떤 알고리즘을 사용하는지에 대한 질문 일 것입니다.
Robert J.

24
Matlab이 결과를 캐싱하지 않는지 확인하십시오. 까다로운 짐승입니다. 먼저 계산이 실제로 수행되고 있는지 확인한 다음 비교하십시오.
rubenvb


10
실제로이 게시물이 정말 흥미 롭다고 생각하지만 더 적절한 벤치 마크를보고 싶습니다. 예를 들어, Matlab R2011a는 멀티 스레딩을 자동으로 사용하고 매트릭스 곱셈은 Intel의 mkl / blas 라이브러리를 사용하여 구현된다고 생각합니다. 따라서 행렬 곱셈을 수행하기 위해 mkl 호출을 사용하면 c ++이 더 빠르다고 생각합니다. 문제는 Matlab의 오버 헤드가 무엇인지에 대한 것입니다. 나는 이것이 행렬 곱셈의 추가 세부 사항에 달려 있지만 위의 숫자는 현재 의미가 없다는 것을 알고 있습니다.
Lucas

1
O (n ^ 3)에서 실행되는 기본 곱셈보다 약 10 배 빠른 큰 정사각 행렬 곱셈에 대해 실행 시간 O (n ^ 2.81)의 "Strassen 알고리즘"을 사용할 수 있습니다. 또한 SSE / AVX를 사용하면 코드 실행 속도가 약 8-20 배 빨라집니다. 모두 함께 matlab보다 AC 구현을 더 빠르게 수행 할 수 있습니다.
DU Jiaen 2016 년

답변:


85

다음 은 Tesla C2070이있는 머신에서 MATLAB R2011a + Parallel Computing Toolbox 를 사용한 결과 입니다.

>> A = rand(1024); gA = gpuArray(A);
% warm up by executing the operations a couple of times, and then:
>> tic, C = A * A; toc
Elapsed time is 0.075396 seconds.
>> tic, gC = gA * gA; toc
Elapsed time is 0.008621 seconds.

MATLAB은 행렬 곱셈을 위해 고도로 최적화 된 라이브러리를 사용하므로 일반 MATLAB 행렬 곱셈이 너무 빠릅니다. gpuArray버전은 사용 MAGMA을 .

업데이트 R2014a를 사용하여 새로운 테슬라 K20c와 시스템에, 그리고 timeitgputimeit기능 :

>> A = rand(1024); gA = gpuArray(A);
>> timeit(@()A*A)
ans =
    0.0324
>> gputimeit(@()gA*gA)
ans =
    0.0022

16 개의 물리적 코어와 Tesla V100이있는 WIN64 시스템에서 R2018b사용하여 업데이트 :

>> timeit(@()A*A)
ans =
    0.0229
>> gputimeit(@()gA*gA)
ans =
   4.8019e-04

(NB : gpuArrayMAGMA에서 cuBLAS로 전환 한 시점에서 (정확히 잊어 버렸습니다) MAGMA는 여전히 일부 gpuArray작업에 사용됩니다 )


이것이 왜 중요한가?
매드 물리학 자

왜 중요한가? MATLAB의 성능이 왜 좋은지 설명하기 위해 MATLAB이 사용하는 라이브러리에 대한 통찰력을 제공하려고 노력했습니다.
Edric

175

이런 종류의 질문은 되풀이되며 "MATLAB은 고도로 최적화 된 라이브러리를 사용합니다"또는 "MATLAB은 MKL을 사용합니다"보다 한 번만 스택 오버플로에서보다 명확하게 대답해야합니다.

역사:

행렬 곱셈 (매트릭스-벡터, 벡터-벡터 곱셈 및 많은 행렬 분해와 함께)은 선형 대수학에서 가장 중요한 문제입니다. 엔지니어들은 초기부터 컴퓨터의 이러한 문제를 해결해 왔습니다.

나는 역사에 대한 전문가는 아니지만, 당시에는 모두 간단한 루프로 FORTRAN 버전을 다시 작성했습니다. 그런 다음 대부분의 선형 대수 문제를 해결하기 위해 필요한 "커널"(기본 루틴)을 식별하면서 일부 표준화가 이루어졌습니다. 그런 다음 이러한 기본 작업은 BLAS (Basic Linear Algebra Subprograms)라는 사양으로 표준화되었습니다. 그런 다음 엔지니어는 코드에서 잘 테스트 된 표준 BLAS 루틴을 호출하여 작업을 훨씬 쉽게 수행 할 수 있습니다.

BLAS :

BLAS는 레벨 1 (스칼라-벡터 및 벡터-벡터 연산을 정의한 첫 번째 버전)에서 레벨 2 (벡터-매트릭스 연산)로 레벨 3 (매트릭스-매트릭스 연산)으로 발전했으며 점점 더 많은 "커널"을 제공하여 더 표준화되었습니다. 그리고 기본적인 선형 대수 연산의 더 많은. 원래 FORTRAN 77 구현은 Netlib 웹 사이트 에서 계속 사용할 수 있습니다 .

더 나은 성능을 향해 :

따라서 수년 동안 (특히 BLAS 레벨 1과 레벨 2 릴리스 : 80 년대 초) 하드웨어는 벡터 작업과 캐시 계층 구조의 출현으로 바뀌 었습니다. 이러한 발전으로 인해 BLAS 서브 루틴의 성능을 크게 향상시킬 수있었습니다. 다른 벤더들은 점점 더 효율적인 BLAS 루틴을 구현했습니다.

나는 모든 역사적 구현을 ​​알지 못하지만 (저는 태어 났거나 어린 시절이 아니 었습니다) 2000 년대 초반 Intel MKL과 GotoBLAS가 가장 눈에 띄었습니다. Matlab은 매우 우수하고 최적화 된 BLAS 인 Intel MKL을 사용하며, 이는 귀하가 보는 뛰어난 성능을 설명합니다.

행렬 곱셈에 대한 기술적 세부 사항 :

그렇다면 왜 Matlab (MKL)이 dgemm배정도 일반 행렬-행렬 곱셈 에서 그렇게 빠른가 ? 간단히 말하면 벡터화와 데이터 캐싱이 우수하기 때문입니다. 보다 복잡한 용어 : Jonathan Moore가 제공 한 기사를 참조하십시오 .

기본적으로 제공 한 C ++ 코드에서 곱셈을 수행 할 때 캐시 친화적 인 것은 아닙니다. 행 배열에 대한 포인터 배열을 만든 것으로 의심되므로 내부 루프에서 "matice2"의 k 번째 열에 대한 액세스 matice2[m][k]가 매우 느립니다. 실제로에 액세스 할 때 matice2[0][k]행렬 배열 0의 k 번째 요소를 가져와야합니다. 그런 다음 다음 반복에서는 matice2[1][k]다른 배열 (배열 1)의 k 번째 요소 인에 액세스해야합니다 . 그런 다음 다음 반복에서 또 다른 배열에 액세스하는 등의 작업을 수행합니다. 전체 행렬 matice2이 가장 높은 캐시 ( 8*1024*1024바이트 크기)에 맞지 않기 때문에 프로그램은 주 메모리에서 원하는 요소를 가져와야합니다. 시각.

액세스가 연속적인 메모리 주소에 있도록 매트릭스를 전치하면 컴파일러가 캐시에서 전체 행을 동시에로드 할 수 있기 때문에 코드가 훨씬 더 빠르게 실행됩니다. 이 수정 된 버전을 사용해보십시오.

timer.start();
float temp = 0;
//transpose matice2
for (int p = 0; p < rozmer; p++)
{
    for (int q = 0; q < rozmer; q++)
    {
        tempmat[p][q] = matice2[q][p];
    }
}
for(int j = 0; j < rozmer; j++)
{
    for (int k = 0; k < rozmer; k++)
    {
        temp = 0;
        for (int m = 0; m < rozmer; m++)
        {
            temp = temp + matice1[j][m] * tempmat[k][m];
        }
        matice3[j][k] = temp;
    }
}
timer.stop();

따라서 캐시 로컬 성이 코드 성능을 얼마나 크게 향상 시켰는지 확인할 수 있습니다. 이제 실제 dgemm구현은이를 매우 광범위한 수준으로 활용합니다. TLB (Translation lookaside buffer, long short short : 효과적으로 캐시 할 수있는 것)의 크기로 정의 된 매트릭스 블록에 대해 곱셈을 수행하여 프로세서로 스트리밍합니다. 처리 할 수있는 데이터의 양입니다. 다른 측면은 벡터화입니다. 프로세서의 벡터화 된 명령어를 사용하여 최적의 명령어 처리량을 얻습니다. 실제로 크로스 플랫폼 C ++ 코드로는 할 수 없습니다.

마지막으로 Strassen 또는 Coppersmith-Winograd 알고리즘이 잘못되었다고 주장하는 사람들은 위에서 언급 한 하드웨어 고려 사항 때문에이 알고리즘을 실제로 구현할 수는 없습니다.


2
방금 캐시 크기의 중요성과 캐시 라인 크기에 데이터를 맞추는 것의 중요성과 소스에 공유 데이터가 없지만 하드웨어에서 공유되는 데이터로 끝나는 멀티 스레드 솔루션의 문제점에 대해 Scott Meyers 비디오를 보았습니다. / core-thread level : youtu.be/WDIkqP4JbkE
WillC

40

이것이 바로 이유 입니다. MATLAB은 C ++ 코드에서 한 것처럼 모든 단일 요소를 반복하여 순진한 행렬 곱셈을 수행하지 않습니다.

물론 C=A*B곱셈 함수를 직접 작성하는 대신 방금 사용했다고 가정합니다 .


19

Matlab은 얼마 전에 LAPACK을 통합 했으므로 행렬 곱셈은 적어도 그렇게 빠른 것을 사용한다고 가정합니다. LAPACK 소스 코드 및 문서를 쉽게 이용할 수 있습니다.

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.140.1785&rep=rep1&type=pdf 에서 Goto와 Van De Geijn의 논문 "고성능 매트릭스 곱셈의 해부학"을 볼 수도 있습니다 .


7
MATLAB은 BLAS / LAPACK 루틴의 ​​최적화 된 구현을 제공하는 Intel MKL 라이브러리를 사용합니다. stackoverflow.com/a/16723946/97160
Amro

11

이에 대한 답은 LAPACKBLAS 라이브러리로 MATLAB 직원이 독점 코드를 작성하는 것이 아니라 MATLAB을 매트릭스 작업에서 맹목적으로 빠르게 만듭니다.

매트릭스 작업에 C ++ 코드에서 LAPACK 및 / 또는 BLAS 라이브러리를 사용하면 MATLAB과 비슷한 성능을 얻을 수 있습니다. 이 라이브러리는 모든 최신 시스템에서 자유롭게 사용할 수 있어야하며 부품은 수십 년 동안 학계에서 개발되었습니다. Intel MKL 과 같은 일부 폐쇄 소스를 포함하여 여러 가지 구현이 있습니다. .

BLAS가 어떻게 고성능을 얻는 지에 대한 논의는 여기에서 가능합니다.


BTW, 내 경험에서 c에서 LAPACK 라이브러리를 직접 호출하는 것은 심각한 고통입니다 (그러나 가치가 있음). 문서를 매우 정확하게 읽어야합니다.


8

행렬 곱셈을 수행 할 때 시간이 걸리는 순진 곱셈 방법을 사용 O(n^3)합니다.

필요한 행렬 곱셈 알고리즘이 O(n^2.4)있습니다. 즉, n=2000알고리즘에서 최고의 알고리즘보다 ~ 100 배 많은 계산이 필요합니다.
효율적인 구현 방법에 대한 자세한 내용은 wikipedia 페이지에서 행렬 곱셈을 확인하십시오.


1024 * 1024 행렬 곱셈 시간은 2048 * 2048 행렬 곱셈 시간의 8 배보다 작기 때문에 MATLAB은 아마도 그러한 알고리즘을 사용할 것입니다! MATLAB 여러분.
Renaud

4
오히려 이론적 인 장점에도 불구하고 그들이 "효율적인"곱셈 알고리즘을 사용하는 것은 의심 스럽다. Strassen의 알고리즘조차도 구현에 어려움이 있으며, 평범하게 읽은 Coppersmith-Winograd 알고리즘 실용적이지 않습니다 (현재). 또한 관련 SO 스레드 : stackoverflow.com/questions/17716565/…
Ernir

이 알고리즘은 매우 큰 행렬에만 해당됩니다.

@ 레노. 그것은 비교적 일정한 오버 헤드의 정의입니다
Mad Physicist

6

Matlab 버전에 따라 이미 GPU를 사용하고 있다고 생각합니다.

또 다른 한가지; Matlab은 매트릭스의 여러 속성을 추적합니다. 대각선, 헤르메스 어 등을 기반으로 알고리즘을 전문화합니다. 어쩌면 전달하는 0 행렬을 기반으로하는 특수화 또는 이와 유사한 것입니까? 어쩌면 반복 된 함수 호출을 캐싱하여 타이밍을 망칠 수 있습니까? 아마도 반복 사용되지 않는 매트릭스 제품을 최적화합니까?

이러한 일이 발생하지 않도록하려면 임의의 숫자로 구성된 행렬을 사용하고 결과를 화면이나 디스크 등으로 인쇄하여 강제로 실행하십시오.


4
ML이 많은 사용자는 아직 GPGPU를 사용하고 있지 않다는 것을 알 수 있습니다. matlab DO의 새 버전은 SSE1 / 2 (최종)를 사용합니다. 하지만 테스트를 마쳤습니다. 요소 별 곱셈을 수행하는 MexFunction은 두 배 빠른 속도로 실행됩니다 A.*B. 따라서 OP는 거의 확실하게 무언가를 다루고 있습니다.
KitsuneYMG

6
Parallel Computing Toolbox 가 포함 된 Matlab 은 CUDA GPU를 사용할 있지만 데이터를 GPU로 푸시해야합니다.
Edric

나는 M1 = single (rand (1024,1024) * 255); M2 = 단일 (rand (1024,1024) * 255); 그리고 M3 = M1 * M2; ... 이진 파일을 이진 파일에 쓰면 모든 것이 매우 빠르게 이루어집니다.
Wolf

3

MATLAB은 Intel MKL (Intel Math Kernel Library) 로 알려진 Intel의 고도로 최적화 된 LAPACK 구현, 특히 dgemm 함수를 사용합니다. 합니다. 속도이 라이브러리는 SIMD 명령어 및 멀티 코어 프로세서를 포함한 프로세서 기능을 활용합니다. 사용하는 특정 알고리즘을 문서화하지 않습니다. C ++에서 Intel MKL을 호출하면 비슷한 성능을 볼 수 있습니다.

MATLAB이 GPU 곱셈에 어떤 라이브러리를 사용하는지 잘 모르겠지만 아마도 nVidia CUBLAS 와 같은 것입니다 .


1
당신 말이 맞지만 이 답을 보셨습니까 ? 그러나 IPP는 MKL이 아니며 MKL은 IPP에 비해 훨씬 뛰어난 선형 대수 성능을 가지고 있습니다. 또한 IPP는 최근 버전에서 매트릭스 수학 모듈을 더 이상 사용하지 않습니다.
chappjc

미안 MKL하지 IPP 의미
gregswiss

당신은 맞습니다 다른 대답은 그것을 커버합니다. 너무 상세해서보고 싶었습니다.
gregswiss

2

"다른 프로그램보다 xxx를 수행 할 때 matlab이 더 빠른 이유"에 대한 일반적인 대답은 matlab에 내장 된 최적화 된 기능이 많이 있다는 것입니다.

자주 사용되는 다른 프로그램에는 이러한 기능이 없기 때문에 사람들은 전문적으로 최적화 된 코드보다 훨씬 느린 자체적 인 창의적인 솔루션을 적용합니다.

이것은 두 가지 방식으로 해석 될 수 있습니다.

1) 일반적인 / 이론적 인 방법 : Matlab은 크게 빠르지 않으며 벤치 마크를 잘못하고 있습니다.

2) 현실적인 방법 :이 물건을 위해 Matlab은 실제로 더 빠릅니다. 왜냐하면 c ++과 같은 언어는 효과적이지 않은 방식으로 너무 쉽게 사용되기 때문입니다.


7
그는 MATLAB 속도를 그가 2 분 안에 작성한 함수의 속도와 비교하고 있습니다. 10 분 안에 더 빠른 기능을 쓰거나 2 시간 안에 훨씬 빠른 기능을 쓸 수 있습니다. MATLAB 직원들은 행렬 곱셈을 빠르게하는 데 2 ​​시간 이상을 보냈습니다.
gnasher729

2

날카로운 대조는 Matlab의 놀라운 최적화 (다른 많은 답변에서 이미 논의했듯이)뿐만 아니라 행렬을 객체로 공식화 한 방식 때문입니다.

매트릭스를 목록의 목록으로 만든 것 같습니다. 목록의 목록에는 행렬 요소를 포함하는 목록에 대한 포인터가 포함됩니다. 포함 된 목록의 위치는 임의로 할당됩니다. 첫 번째 인덱스 (행 번호?)를 반복하면서 메모리 액세스 시간이 매우 중요합니다. 비교해 보면, 다음 방법을 사용하여 행렬을 단일 목록 / 벡터로 구현해 보지 않겠습니까?

#include <vector>

struct matrix {
    matrix(int x, int y) : n_row(x), n_col(y), M(x * y) {}
    int n_row;
    int n_col;
    std::vector<double> M;
    double &operator()(int i, int j);
};

double &matrix::operator()(int i, int j) {
    return M[n_col * i + j];
}

플롭의 수가 동일하도록 동일한 곱셈 알고리즘을 사용해야합니다. (크기 n의 정방 행렬의 경우 n ^ 3)

결과를 이전과 동일한 시스템에서 비교할 수 있도록 시간을 내야합니다. 비교를 통해 메모리 액세스 시간이 얼마나 중요한지 정확하게 알 수 있습니다!


2

멀티 스레딩을 사용하지 않기 때문에 C ++에서는 속도가 느립니다. 기본적으로 A = BC 인 경우 모두 행렬 인 경우 A의 첫 번째 행은 두 번째 행과 독립적으로 계산할 수 있습니다. A, B 및 C가 모두 n 개의 행렬 인 경우 곱셈 속도를 높일 수 있습니다. n ^ 2의 계수

a_ {i, j} = sum_ {k} b_ {i, k} c_ {k, j}

예를 들어 Eigen [ http://eigen.tuxfamily.org/dox/GettingStarted.html ]을 사용하는 경우 멀티 스레딩이 내장되어 있으며 스레드 수를 조정할 수 있습니다.


2

MATLAB 은 처음에 수치 선형 대수 (매트릭스 조작)를 위해 개발 된 프로그래밍 언어 이므로 매트릭스 곱셈을 위해 특별히 개발 된 라이브러리가 있습니다. 그리고 지금은 MATLAB은 또한 사용할 수있는 GPU를 (그래픽 처리 장치) 추가를위한이.

그리고 우리가 계산 결과를 보면 :

             1024x1024   2048x2048   4096x4096
             ---------   ---------   ---------
CUDA C (ms)      43.11      391.05     3407.99
C++ (ms)       6137.10    64369.29   551390.93
C# (ms)       10509.00   300684.00  2527250.00
Java (ms)      9149.90    92562.28   838357.94
MATLAB (ms)      75.01      423.10     3133.90

MATLAB이 행렬 곱셈에서 너무 빠르다는 것을 알 수 있습니다. CUDA C (NVIDIA의 프로그래밍 언어)는 MATLAB보다 더 나은 결과를 보여줍니다. CUDA C에는 특히 행렬 곱셈을 위해 개발 된 라이브러리가 있으며 GPU를 사용합니다.

MATLAB의 짧은 역사

뉴 멕시코 대학교 (University of New Mexico)의 컴퓨터 과학 부서 회장 인 Cleve Moler는 1970 년대 후반에 MATLAB을 개발하기 시작했습니다. 그는 학생들에게 LINPACK (숫자 선형 대수를 수행하기위한 소프트웨어 라이브러리) 및 EISPACK에 액세스 할 수 있도록 설계했습니다.Fortran을 배울 필요없이 (선형 대수의 수치 계산을위한 소프트웨어 라이브러리입니다). 곧 다른 대학으로 퍼져 응용 수학 커뮤니티 내에서 많은 관중을 발견했습니다. 엔지니어 인 Jack Little은 1983 년 Stanford University를 방문한 Moler와 함께 방문했습니다. 상업적 잠재력을 인식하고 Moler와 Steve Bangert와 합류했습니다. 그들은 C로 MATLAB을 다시 쓰고 1984 년에 MathWorks를 설립하여 개발을 계속했습니다. 이 재 작성 라이브러리는 JACKPAC으로 알려져 있습니다. 2000 년 MATLAB은 매트릭스 조작을위한 최신 라이브러리 세트 인 LAPACK (숫자 선형 대수학을위한 표준 소프트웨어 라이브러리)을 사용하도록 재 작성되었습니다.

출처

CUDA C 란 무엇인가

CUDA C는 OpenGL (Open Graphics Library) 과 같은 행렬 곱셈을 위해 특별히 개발 된 라이브러리도 사용합니다 . 또한 GPU 및 Direct3D (MS Windows의 경우)도 사용합니다.

CUDA 플랫폼은 같은 C, C ++ 및 포트란과 같은 프로그래밍 언어와 함께 작동하도록 설계되었습니다. 이 접근성은 그래픽 프로그래밍의 고급 기술이 필요한 Direct3DOpenGL 과 같은 이전 API와 달리 병렬 프로그래밍 전문가가 GPU 리소스를 더 쉽게 사용할 수 있도록합니다 . 또한 CUDA는 OpenACCOpenCL 과 같은 프로그래밍 프레임 워크를 지원합니다 .

여기에 이미지 설명을 입력하십시오

CUDA 처리 흐름의 예 :

  1. 메인 메모리에서 GPU 메모리로 데이터 복사
  2. CPU는 GPU 계산 커널을 시작합니다
  3. GPU의 CUDA 코어는 커널을 병렬로 실행
  4. GPU 메모리에서 메인 메모리로 결과 데이터 복사

CPU 및 GPU 실행 속도 비교

인텔 제온 프로세서 X5650에서 64, 128, 512, 1024 및 2048의 그리드 크기에 대해 50 개의 시간 단계를 실행하고 NVIDIA Tesla C2050 GPU를 사용하는 데 걸리는 시간을 측정 한 벤치 마크를 실행했습니다.

여기에 이미지 설명을 입력하십시오

그리드 크기가 2048 인 경우 알고리즘은 CPU에서 계산 시간이 CPU에서 1 분 이상에서 10 초 미만으로 7.5 배 감소 함을 보여줍니다. 로그 스케일 플롯은 CPU가 실제로 작은 그리드 크기에 대해 더 빠르다는 것을 보여줍니다. 그러나 기술이 발전하고 발전함에 따라 GPU 솔루션은 점점 더 작은 문제를 처리 할 수있게되었습니다.

출처

CUDA C 프로그래밍 가이드 소개 :

에 의해 그림과 같이 실시간, 고화질 3D 그래픽에 대한 만족할 줄 모르는 시장의 수요에 힘 입어 프로그래머블 그래픽 프로세서 유닛 또는 GPU는 엄청난 계산 마력과 매우 높은 메모리 대역폭과 고도의 병렬, 멀티 스레드, 매니 코어 프로세서로 진화 Figure 1하고 Figure 2.

그림 1. CPU 및 GPU의 초당 부동 소수점 연산

여기에 이미지 설명을 입력하십시오

그림 2 . CPU 및 GPU의 메모리 대역폭

여기에 이미지 설명을 입력하십시오

CPU와 GPU 간 부동 소수점 기능의 불일치가 발생하는 이유는 GPU가 컴퓨팅 집약적이며 병렬 처리가 매우 정확하고 그래픽 렌더링에 관한 것이므로 데이터 처리에 더 많은 트랜지스터가 사용되도록 설계 되었기 때문입니다 로 개략적으로 설명 된 것처럼 데이터 캐싱 및 흐름 제어가 아닙니다 Figure 3.

그림 3 . GPU는 더 많은 트랜지스터를 데이터 처리에 전념

여기에 이미지 설명을 입력하십시오

보다 구체적으로, GPU는 데이터 병렬 계산으로 표현 될 수있는 문제를 해결하는 데 특히 적합합니다. 동일한 프로그램이 많은 데이터 요소에서 병렬로 실행되며 높은 산술 강도와 산술 연산 대 메모리 연산의 비율입니다. 각 데이터 요소에 대해 동일한 프로그램이 실행되므로 정교한 흐름 제어에 대한 요구 사항이 낮아지고 많은 데이터 요소에서 실행되며 높은 산술 강도를 가지므로 메모리 액세스 대기 시간은 빅 데이터 캐시 대신 계산으로 숨길 수 있습니다 .

데이터 병렬 처리는 데이터 요소를 병렬 처리 스레드에 맵핑합니다. 큰 데이터 세트를 처리하는 많은 응용 프로그램은 데이터 병렬 프로그래밍 모델을 사용하여 계산 속도를 높일 수 있습니다. 3D 렌더링에서 큰 픽셀 및 정점 세트는 병렬 스레드에 매핑됩니다. 유사하게, 렌더링 된 이미지의 후 처리, 비디오 인코딩 및 디코딩, 이미지 스케일링, 스테레오 비전 및 패턴 인식과 같은 이미지 및 미디어 프로세싱 애플리케이션은 이미지 블록 및 픽셀을 병렬 프로세싱 스레드에 매핑 할 수있다. 실제로, 이미지 렌더링 및 프로세싱 분야 외부의 많은 알고리즘은 일반적인 신호 프로세싱 또는 물리 시뮬레이션에서 계산 금융 또는 컴퓨팅 생물학에 이르기까지 데이터 병렬 프로세싱에 의해 가속화된다.

출처

고급 독해


흥미로운 팩

Matlab보다 빠른 C ++ 행렬 곱셈을 작성했지만 약간의주의가 필요했습니다. (Matlab이 GPU를 사용하기 전에).

이 답변 에서 인용 .


2
마지막 인용은 "사실"이 아니며 공허한 자랑입니다. 그 사람은 게시 한 이후 몇 가지 코드 요청을 받았습니다. 그러나 코드가 보이지 않습니다.
Cris Luengo

1
GPU에서 얼마나 빨리 계산을 수행 할 수 있는지에 대한 설명은 문제를 전혀 다루지 않습니다. 우리는 모두 128 개의 작은 코어가 2 개의 큰 코어보다 동일한 단조로운 작업을 더 많이 수행 할 수 있음을 알고 있습니다. "이제 MATLAB은이를 위해 GPU (Graphics Processing Unit)도 추가로 사용할 수 있습니다." 예, 그러나 기본적으로는 아닙니다. 정규 행렬 곱셈은 여전히 ​​BLAS를 사용합니다.
Cris Luengo

@CrisLuengo, 알았어, 사실이 아니다! 어쩌면 당신은 그의 "자랑"에 대해 옳을 수도 있습니다 – 우리는 그것에 대해 알지 못하며 왜 그가 대답하지 않는지 알지 못합니다. 두 번째 의견 : GPU에서 계산에 대한 설명은 선형 대수학에서 행렬 곱셈의 경우 부동 소수점 연산을 사용하기 때문에 질문에 대답합니다. 어쩌면 모든 사람들이 이해할 수있는 것은 아니지만이 기본 사항을 이해해야한다고 생각합니다. 다른 경우에는 행렬에 대한 기사를 읽기 전에 먼저이 기본 사항을 배워야합니다. 다른 사람이 저에 대해 글을 쓰면이 내용을 추가하겠습니다. 감사합니다!
Bharata

@CrisLuengo, 나는 단어를 썼다 "additionally". 그것은 사용될 수 있다는 것을 의미합니다. 또한 정규 행렬 곱셈은 여전히 ​​소프트웨어 라이브러리를 사용합니다. 이해하기 쉽게 게시물을 변경해야한다고 생각하십니까? 귀하의 의견에 감사드립니다!
Bharata
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.