Tại sao MATLAB lại nhân nhanh như vậy?


190

Tôi đang thực hiện một số điểm chuẩn với CUDA, C ++, C #, Java và sử dụng MATLAB để xác minh và tạo ma trận. Khi tôi thực hiện phép nhân ma trận với MATLAB, 2048x2048và các ma trận lớn hơn gần như được nhân lên ngay lập tức.

             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

Chỉ có CUDA là cạnh tranh, nhưng tôi nghĩ rằng ít nhất C ++ sẽ hơi gần và không chậm hơn 60 lần. Tôi cũng không biết phải nghĩ gì về kết quả C #. Thuật toán chỉ là giống như C ++ và Java, nhưng có một bước nhảy khổng lồ 2048từ 1024.

Làm thế nào để MATLAB thực hiện phép nhân ma trận nhanh như vậy?

Mã 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
Có lẽ đó là một câu hỏi về thuật toán mà bạn sử dụng.
Robert J.

24
Hãy chắc chắn rằng Matlab không lưu trữ kết quả của bạn, đó là một con quái vật khó khăn. Đầu tiên đảm bảo tính toán thực sự được thực hiện, và sau đó so sánh.
rubenvb


10
Tôi thực sự nghĩ rằng bài đăng này thực sự thú vị nhưng tôi thực sự muốn xem điểm chuẩn phù hợp hơn. Ví dụ, tôi nghĩ rằng Matlab R2011a đang sử dụng đa luồng tự động và phép nhân ma trận được triển khai bằng thư viện mkl / blas của Intel. Vì vậy, tôi đoán rằng c ++ sẽ nhanh hơn nếu người ta sử dụng lệnh gọi mkl để thực hiện phép nhân ma trận. Câu hỏi sau đó sẽ là chi phí của Matlab là gì. Tôi biết rằng điều này phụ thuộc vào các chi tiết bổ sung của phép nhân ma trận nhưng các con số trên hiện tại khá vô nghĩa.
Lucas

1
bạn có thể sử dụng "Thuật toán Strassen" của thời gian chạy O (n ^ 2.81) để nhân ma trận vuông lớn, nhanh hơn khoảng 10 lần so với phép nhân gốc chạy trong O (n ^ 3). SSE / AVX cũng có thể giúp bạn nhanh hơn khoảng 8-20 lần để thực thi mã. tất cả cùng nhau bạn có thể thực hiện ac nhanh hơn so với của matlab.
DU Jiaen

Câu trả lời:


85

Đây là kết quả của tôi khi sử dụng MATLAB R2011a + Hộp công cụ tính toán song song trên máy có Tesla C2070:

>> 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 sử dụng các thư viện được tối ưu hóa cao để nhân ma trận, đó là lý do tại sao phép nhân ma trận MATLAB đơn giản quá nhanh. CácgpuArray phiên bản sử dụng MAGMA .

Cập nhật bằng R2014a trên một máy với một Tesla K20c, và mới timeitgputimeitchức năng:

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

Cập nhật bằng R2018b trên máy WIN64 với 16 lõi vật lý và Tesla V100:

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

(NB: tại một số điểm (tôi quên khi chính xác) gpuArrayđã chuyển từ MAGMA sang cuBLAS - MAGMA vẫn được sử dụng cho một số gpuArrayhoạt động)


Vì sao vấn đề này?
Nhà vật lý điên

Tại sao có vấn đề gì? Tôi đã cố gắng cung cấp một số cái nhìn sâu sắc về các thư viện được MATLAB sử dụng trong các tình huống khác nhau để giải thích tại sao hiệu suất của MATLAB lại tốt - tức là vì nó sử dụng các thư viện số được tối ưu hóa cao.
Edric

175

Loại câu hỏi này được lặp lại và cần được trả lời rõ ràng hơn "MATLAB sử dụng các thư viện được tối ưu hóa cao" hoặc "MATLAB sử dụng MKL" một lần trên Stack Overflow.

Lịch sử:

Phép nhân ma trận (cùng với phép nhân vectơ, phép nhân vectơ và nhiều phép phân tách ma trận) là (những) vấn đề quan trọng nhất trong đại số tuyến tính. Các kỹ sư đã giải quyết những vấn đề này với máy tính từ những ngày đầu.

Tôi không phải là một chuyên gia về lịch sử, nhưng rõ ràng hồi đó, mọi người chỉ viết lại phiên bản FORTRAN của mình bằng các vòng lặp đơn giản. Một số tiêu chuẩn hóa sau đó đã xuất hiện, với việc xác định "hạt nhân" (các thói quen cơ bản) mà hầu hết các vấn đề đại số tuyến tính cần thiết để được giải quyết. Các hoạt động cơ bản này sau đó đã được chuẩn hóa trong một đặc tả gọi là: Chương trình con đại số tuyến tính cơ bản (BLAS). Các kỹ sư sau đó có thể gọi các thường trình BLAS được kiểm tra tốt này trong mã của họ, giúp công việc của họ dễ dàng hơn nhiều.

BLAS:

BLAS đã phát triển từ cấp 1 (phiên bản đầu tiên xác định các phép toán vectơ vô hướng và vectơ vectơ) sang cấp 2 (hoạt động ma trận vectơ) đến cấp 3 (hoạt động ma trận ma trận) và cung cấp ngày càng nhiều "hạt nhân" được chuẩn hóa hơn và nhiều hơn các hoạt động đại số tuyến tính cơ bản. Các triển khai FORTRAN 77 ban đầu vẫn có sẵn trên trang web của Netlib .

Hướng tới hiệu suất tốt hơn:

Vì vậy, qua nhiều năm (đáng chú ý là giữa các bản phát hành BLAS cấp 1 và cấp 2: đầu thập niên 80), phần cứng đã thay đổi, với sự ra đời của các hoạt động véc tơ và phân cấp bộ đệm. Những phát triển này đã làm tăng đáng kể hiệu năng của các chương trình con BLAS. Các nhà cung cấp khác nhau sau đó đã đi kèm với việc thực hiện các thói quen BLAS ngày càng hiệu quả hơn.

Tôi không biết tất cả các triển khai lịch sử (lúc đó tôi chưa sinh ra hoặc là một đứa trẻ), nhưng hai trong số những điều đáng chú ý nhất đã xuất hiện vào đầu những năm 2000: Intel MKL và GotoBLAS. Matlab của bạn sử dụng Intel MKL, đây là một BLAS rất tốt, được tối ưu hóa và điều đó giải thích hiệu suất tuyệt vời mà bạn thấy.

Chi tiết kỹ thuật về nhân ma trận:

Vậy tại sao Matlab (MKL) lại nhanh như vậy dgemm(phép nhân ma trận tổng quát ma trận tổng hợp chính xác kép)? Nói một cách đơn giản: bởi vì nó sử dụng vector hóa và lưu trữ dữ liệu tốt. Trong các điều khoản phức tạp hơn: xem bài viết được cung cấp bởi Jonathan Moore.

Về cơ bản, khi bạn thực hiện phép nhân của mình trong mã C ++ mà bạn cung cấp, bạn hoàn toàn không thân thiện với bộ đệm. Vì tôi nghi ngờ bạn đã tạo một mảng các con trỏ tới các mảng hàng, nên các truy cập của bạn trong vòng lặp bên trong của bạn đến cột thứ k của "matice2": matice2[m][k]rất chậm. Thật vậy, khi bạn truy cập matice2[0][k], bạn phải lấy phần tử thứ k của mảng 0 trong ma trận của bạn. Sau đó, trong lần lặp tiếp theo, bạn phải truy cập matice2[1][k], đó là phần tử thứ k của mảng khác (mảng 1). Sau đó, trong lần lặp lại tiếp theo, bạn truy cập vào một mảng khác, v.v ... Vì toàn bộ ma trận matice2không thể phù hợp với bộ nhớ cache cao nhất (nó8*1024*1024 byte lớn), chương trình phải lấy phần tử mong muốn từ bộ nhớ chính, mất rất nhiều thời gian.

Nếu bạn chỉ chuyển đổi ma trận, để các truy cập sẽ ở trong các địa chỉ bộ nhớ liền kề, mã của bạn sẽ chạy nhanh hơn nhiều vì giờ đây trình biên dịch có thể tải toàn bộ các hàng trong bộ đệm cùng một lúc. Chỉ cần thử phiên bản sửa đổi này:

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();

Vì vậy, bạn có thể thấy làm thế nào chỉ bộ nhớ cache cục bộ tăng hiệu suất mã của bạn khá đáng kể. Bây giờ là thậtdgemm triển khai thực khai thác đến mức rất rộng: Chúng thực hiện phép nhân trên các khối của ma trận được xác định bởi kích thước của TLB (Bộ đệm dịch thuật, câu chuyện dài: những gì có thể được lưu trữ hiệu quả), để chúng truyền đến bộ xử lý chính xác lượng dữ liệu nó có thể xử lý. Khía cạnh khác là vector hóa, họ sử dụng các hướng dẫn được vector hóa của bộ xử lý cho thông lượng hướng dẫn tối ưu, điều mà bạn thực sự không thể làm được từ mã C ++ đa nền tảng của mình.

Cuối cùng, mọi người cho rằng đó là do thuật toán của Strassen hay Coppersmith Nhận Win giác là sai, cả hai thuật toán này đều không thể thực hiện được trong thực tế, vì những cân nhắc về phần cứng đã đề cập ở trên.


2
Tôi vừa xem video của Scott Meyers về tầm quan trọng của kích thước bộ đệm và dữ liệu phù hợp với kích thước dòng bộ đệm và các vấn đề bạn có thể gặp phải với các giải pháp đa luồng không có dữ liệu chia sẻ trong nguồn nhưng kết thúc bằng dữ liệu được chia sẻ ở phần cứng / mức lõi-luồng: youtu.be/WDIkqP4JbkE
WillC

40

Đây là lý do tại sao . MATLAB không thực hiện phép nhân ma trận ngây thơ bằng cách lặp qua từng phần tử theo cách bạn đã làm trong mã C ++ của mình.

Tất nhiên tôi giả sử rằng bạn chỉ sử dụng C=A*Bthay vì tự viết một hàm nhân.


19

Matlab đã kết hợp LAPACK một thời gian trước đây, vì vậy tôi cho rằng phép nhân ma trận của họ sử dụng một cái gì đó nhanh nhất. Mã nguồn và tài liệu LAPACK có sẵn.

Bạn cũng có thể xem bài viết "Giải phẫu nhân ma trận hiệu suất cao" của Goto và Van De Geijn tại http://citeseerx.ist.psu.edu/viewdoc/doad?doi=10.1.1.140.1785&rep=rep1&type=pdf


7
MATLAB sử dụng Thư viện Intel MKL cung cấp triển khai tối ưu các thói quen BLAS / LAPACK: stackoverflow.com/a/16723946/97160
Amro

11

Câu trả lời là các thư viện LAPACKBLAS làm cho MATLAB nhanh chóng hoạt động nhanh chóng, không phải bất kỳ mã độc quyền nào của folks tại MATLAB.

Sử dụng các thư viện LAPACK và / hoặc BLAS trong mã C ++ của bạn cho các hoạt động ma trận và bạn sẽ có được hiệu suất tương tự như MATLAB. Các thư viện này nên có sẵn miễn phí trên bất kỳ hệ thống hiện đại nào và các bộ phận đã được phát triển qua nhiều thập kỷ ở học viện. Lưu ý rằng có nhiều triển khai, bao gồm một số nguồn đóng như Intel MKL .

Một cuộc thảo luận về cách BLAS có hiệu suất cao có sẵn ở đây.


BTW, đó là một nỗi đau nghiêm trọng trong kinh nghiệm của tôi khi gọi các thư viện LAPACK trực tiếp từ c (nhưng đáng giá). Bạn cần đọc tài liệu RẤT chính xác.


8

Khi thực hiện phép nhân ma trận, bạn sử dụng phương pháp nhân ngây thơ cần có thời gian O(n^3).

Có tồn tại thuật toán nhân ma trận O(n^2.4). Điều đó có nghĩa là tại n=2000thuật toán của bạn yêu cầu tính toán gấp 100 lần so với thuật toán tốt nhất.
Bạn thực sự nên kiểm tra trang wikipedia để nhân ma trận để biết thêm thông tin về các cách hiệu quả để thực hiện nó.


và MATLAB có thể sử dụng thuật toán như vậy vì thời gian nhân ma trận 1024 * 1024 nhỏ hơn 8 lần thời gian cho phép nhân ma trận 2048 * 2048! Làm tốt lắm các chàng trai MATLAB.
Đổi mới

4
Tôi khá nghi ngờ họ sử dụng các thuật toán nhân "hiệu quả", mặc dù có những lợi thế về mặt lý thuyết. Ngay cả thuật toán của Strassen cũng gặp khó khăn khi triển khai và thuật toán Coppersmith tầm Win giác mà bạn có thể đã đọc về việc đơn giản là không thực tế (ngay bây giờ). Ngoài ra, chủ đề SO liên quan: stackoverflow.com/questions/17716565/ từ
Ernir

Thuật toán đó chỉ dành cho ma trận cực lớn.

@Renaud. Đó là định nghĩa về chi phí tương đối ổn định
Nhà vật lý điên

6

Tùy thuộc vào phiên bản Matlab của bạn, tôi tin rằng nó có thể đang sử dụng GPU của bạn.

Cái khác; Matlab theo dõi nhiều thuộc tính của ma trận của bạn; với đường chéo, hermetian, v.v., và chuyên về các thuật toán của nó dựa trên đó. Có lẽ nó chuyên dựa trên ma trận số không bạn đang vượt qua nó, hoặc một cái gì đó tương tự? Có lẽ đó là bộ nhớ đệm lặp lại các cuộc gọi chức năng, làm rối loạn thời gian của bạn? Có lẽ nó tối ưu hóa ra các sản phẩm ma trận không sử dụng lặp đi lặp lại?

Để bảo vệ chống lại những điều như vậy xảy ra, hãy sử dụng ma trận các số ngẫu nhiên và đảm bảo bạn buộc thực thi bằng cách in kết quả ra màn hình hoặc đĩa hoặc somesuch.


4
Là một người dùng ML nặng, tôi có thể nói với bạn rằng họ chưa sử dụng GPGPU. Phiên bản mới của MATLAB DO sử dụng SSE1 / 2 (cuối cùng). Nhưng tôi đã làm các bài kiểm tra. Một MexFactor thực hiện phép nhân phần tử khôn ngoan chạy nhanh gấp đôi A.*B. Vì vậy, OP gần như chắc chắn sẽ làm điều gì đó.
KitsuneYMG

6
Matlab với Parallel Computing Toolbox có thể sử dụng GPU CUDA, nhưng rõ ràng - bạn phải đẩy dữ liệu lên GPU.
Edric

Tôi sử dụng M1 = đơn (rand (1024,1024) * 255); M2 = đơn (rand (1024,1024) * 255); và M3 = M1 * M2; ... sau đó ghi vào tệp nhị phân của số float, tất cả được thực hiện rất nhanh.
Sói

3

MATLAB sử dụng triển khai LAPACK được tối ưu hóa cao từ Intel được gọi là Thư viện hạt nhân toán học Intel (Intel MKL) - cụ thể là chức năng dgemm . Tốc độ Thư viện này tận dụng các tính năng của bộ xử lý bao gồm các hướng dẫn SIMD và bộ xử lý đa lõi. Họ không ghi lại thuật toán cụ thể mà họ sử dụng. Nếu bạn gọi Intel MKL từ C ++, bạn sẽ thấy hiệu suất tương tự.

Tôi không chắc MATLAB sử dụng thư viện nào để nhân GPU nhưng có lẽ là thứ gì đó giống như nVidia CUBLAS .


1
Bạn đúng, nhưng bạn đã thấy câu trả lời này ? Tuy nhiên, IPP không phải là MKL và MKL có hiệu suất đại số tuyến tính vượt trội hơn nhiều so với IPP. Ngoài ra, IPP không chấp nhận mô-đun toán ma trận của họ trong các phiên bản gần đây.
chappjc

Xin lỗi, ý tôi là MKL không phải là IPP
gregswiss

Bạn đúng câu trả lời khác bao gồm nó. Thật dài dòng tôi đã bỏ lỡ nó.
gregswiss

2

Câu trả lời chung cho "Tại sao matlab nhanh hơn khi thực hiện xxx so với các chương trình khác" là matlab có rất nhiều chức năng được tối ưu hóa tích hợp.

Các chương trình khác được sử dụng thường không có các chức năng này, vì vậy mọi người áp dụng các giải pháp sáng tạo của riêng họ, chậm hơn so với mã được tối ưu hóa chuyên nghiệp.

Điều này có thể được hiểu theo hai cách:

1) Cách phổ biến / lý thuyết: Matlab không nhanh hơn đáng kể, bạn chỉ đang làm sai chuẩn

2) Cách thực tế: Đối với công cụ này, Matlab nhanh hơn trong thực tế vì các ngôn ngữ như c ++ quá dễ sử dụng theo những cách không hiệu quả.


7
Anh ta so sánh tốc độ MATLAB với tốc độ của một chức năng mà anh ta đã viết trong hai phút. Tôi có thể viết một chức năng nhanh hơn trong 10 phút, hoặc một chức năng nhanh hơn nhiều trong hai giờ. Các anh chàng MATLAB đã dành hơn hai giờ để nhân lên ma trận nhanh chóng.
gnasher729

2

Sự tương phản rõ nét không chỉ do tối ưu hóa đáng kinh ngạc của Matlab (như đã được thảo luận bởi nhiều câu trả lời khác), mà còn ở cách bạn xây dựng ma trận như một đối tượng.

Có vẻ như bạn đã tạo ra một danh sách các danh sách? Một danh sách các danh sách chứa các con trỏ tới các danh sách chứa các phần tử ma trận của bạn. Các vị trí của danh sách chứa được chỉ định tùy ý. Khi bạn đang lặp qua chỉ mục đầu tiên của bạn (số hàng?), Thời gian truy cập bộ nhớ là rất đáng kể. Để so sánh, tại sao bạn không thử triển khai ma trận dưới dạng một danh sách / vectơ bằng phương pháp sau?

#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];
}

Thuật toán nhân giống nhau nên được sử dụng sao cho số lượng flop là như nhau. (n ^ 3 cho ma trận vuông có kích thước n)

Tôi đang yêu cầu bạn tính thời gian để kết quả tương đương với những gì bạn đã có trước đó (trên cùng một máy). Với sự so sánh, bạn sẽ cho thấy chính xác thời gian truy cập bộ nhớ đáng kể như thế nào!


2

Nó chậm trong C ++ vì bạn không sử dụng đa luồng. Về cơ bản, nếu A = BC, trong đó chúng đều là ma trận, hàng đầu tiên của A có thể được tính độc lập với hàng thứ 2, v.v ... Nếu A, B và C đều là n theo n ma trận, bạn có thể tăng tốc độ nhân lên một yếu tố của n ^ 2, như

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

Nếu bạn sử dụng, giả sử, Eigen [ http: // eigen.tuxf Family.org/dox/GettingStarted.html ], đa luồng được tích hợp sẵn và số lượng luồng có thể điều chỉnh.


2

Bởi vì MATLAB là ngôn ngữ lập trình lúc đầu được phát triển cho đại số tuyến tính số (thao tác ma trận), có thư viện được phát triển đặc biệt cho phép nhân ma trận. Và bây giờ MATLAB cũng có thể sử dụng GPU (đơn vị xử lý đồ họa) cho việc này.

Và nếu chúng tôi xem kết quả tính toán của bạn:

             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

sau đó chúng ta có thể thấy rằng không chỉ MATLAB nhanh như vậy trong phép nhân ma trận: CUDA C (ngôn ngữ lập trình từ NVIDIA) có một số kết quả tốt hơn MATLAB. CUDA C cũng có các thư viện được phát triển đặc biệt để nhân ma trận và nó sử dụng GPU.

Lịch sử ngắn của MATLAB

Cleve Moler, chủ tịch của khoa khoa học máy tính tại Đại học New Mexico, bắt đầu phát triển MATLAB vào cuối những năm 1970. Ông đã thiết kế nó để cho sinh viên của mình truy cập vào LINPACK (một thư viện phần mềm để thực hiện đại số tuyến tính số) và EISPACK(là một thư viện phần mềm để tính toán đại số tuyến tính) mà không cần phải học Fortran. Nó sớm lan sang các trường đại học khác và tìm thấy một lượng khán giả mạnh mẽ trong cộng đồng toán học ứng dụng. Jack Little, một kỹ sư, đã được tiếp xúc với nó trong chuyến thăm Moler đến Đại học Stanford năm 1983. Nhận thấy tiềm năng thương mại của mình, anh đã tham gia với Moler và Steve Bangert. Họ viết lại MATLAB bằng C và thành lập MathWorks vào năm 1984 để tiếp tục phát triển. Những thư viện viết lại này được gọi là JACKPAC. Năm 2000, MATLAB đã được viết lại để sử dụng một bộ thư viện mới hơn để thao tác ma trận, LAPACK (là một thư viện phần mềm tiêu chuẩn cho đại số tuyến tính số).

Nguồn

CUDA C là gì

CUDA C cũng sử dụng các thư viện được phát triển đặc biệt cho các phép nhân ma trận như OpenGL (Thư viện đồ họa mở). Nó cũng sử dụng GPU và Direct3D (trên MS Windows).

Các nền tảng CUDA được thiết kế để làm việc với các ngôn ngữ lập trình như C, C ++ và Fortran. Khả năng truy cập này giúp các chuyên gia lập trình song song sử dụng tài nguyên GPU dễ dàng hơn, trái ngược với các API trước đó như Direct3DOpenGL , đòi hỏi các kỹ năng nâng cao trong lập trình đồ họa. Ngoài ra, CUDA hỗ trợ các khung lập trình như OpenACCOpenCL .

nhập mô tả hình ảnh ở đây

Ví dụ về quy trình xử lý CUDA:

  1. Sao chép dữ liệu từ bộ nhớ chính sang bộ nhớ GPU
  2. CPU khởi tạo hạt nhân tính toán GPU
  3. Các lõi CUDA của GPU thực thi song song kernel
  4. Sao chép dữ liệu kết quả từ bộ nhớ GPU vào bộ nhớ chính

So sánh tốc độ thực thi CPU và GPU

Chúng tôi đã chạy một điểm chuẩn trong đó chúng tôi đã đo lượng thời gian cần thiết để thực hiện 50 bước thời gian cho các kích thước lưới 64, 128, 512, 1024 và 2048 trên Bộ xử lý Intel Xeon X5650 và sau đó sử dụng GPU NVIDIA Tesla C2050.

nhập mô tả hình ảnh ở đây

Đối với kích thước lưới 2048, thuật toán cho thấy thời gian tính toán giảm 7,5 lần từ hơn một phút trên CPU xuống dưới 10 giây trên GPU. Biểu đồ tỷ lệ nhật ký cho thấy CPU thực sự nhanh hơn đối với các kích thước lưới nhỏ. Tuy nhiên, khi công nghệ phát triển và trưởng thành, các giải pháp GPU ngày càng có khả năng xử lý các vấn đề nhỏ hơn, một xu hướng mà chúng tôi dự kiến ​​sẽ tiếp tục.

Nguồn

Từ phần giới thiệu cho Hướng dẫn lập trình CUDA C:

Được thúc đẩy bởi nhu cầu thị trường vô độ đối với đồ họa 3D thời gian thực, độ phân giải cao, Bộ xử lý đồ họa hoặc GPU có thể lập trình đã phát triển thành một bộ xử lý nhiều lõi song song, đa luồng với mã lực tính toán cực lớn và băng thông bộ nhớ rất cao, như được minh họa bởi Figure 1Figure 2.

Hình 1. Hoạt động điểm nổi mỗi giây cho CPU và GPU

nhập mô tả hình ảnh ở đây

Hình 2 . Băng thông bộ nhớ cho CPU và GPU

nhập mô tả hình ảnh ở đây

Lý do đằng sau sự khác biệt về khả năng của dấu phẩy động giữa CPU và GPU là vì GPU chuyên dùng cho tính toán song song chuyên sâu, tính toán cao - chính xác là kết xuất đồ họa là gì - và do đó được thiết kế sao cho nhiều bóng bán dẫn được dành cho xử lý dữ liệu thay vì lưu trữ dữ liệu và điều khiển luồng, như được minh họa bằng sơ đồ Figure 3.

Hình 3 . GPU dành nhiều bóng bán dẫn hơn để xử lý dữ liệu

nhập mô tả hình ảnh ở đây

Cụ thể hơn, GPU đặc biệt phù hợp để giải quyết các vấn đề có thể được biểu thị dưới dạng tính toán song song dữ liệu - cùng một chương trình được thực hiện trên nhiều phần tử dữ liệu - với cường độ số học cao - tỷ lệ của các phép toán số học cho các hoạt động bộ nhớ. Bởi vì cùng một chương trình được thực thi cho từng thành phần dữ liệu, nên yêu cầu kiểm soát luồng tinh vi thấp hơn và do nó được thực thi trên nhiều thành phần dữ liệu và có cường độ số học cao, độ trễ truy cập bộ nhớ có thể được ẩn bằng các phép tính thay vì lưu trữ dữ liệu lớn .

Xử lý song song dữ liệu ánh xạ các phần tử dữ liệu đến các luồng xử lý song song. Nhiều ứng dụng xử lý các tập dữ liệu lớn có thể sử dụng mô hình lập trình song song dữ liệu để tăng tốc các tính toán. Trong kết xuất 3D, các tập hợp pixel và đỉnh lớn được ánh xạ tới các luồng song song. Tương tự, các ứng dụng xử lý hình ảnh và phương tiện như xử lý hậu kỳ của hình ảnh được kết xuất, mã hóa và giải mã video, chia tỷ lệ hình ảnh, tầm nhìn âm thanh nổi và nhận dạng mẫu có thể ánh xạ các khối hình ảnh và pixel thành các luồng xử lý song song. Trên thực tế, nhiều thuật toán ngoài lĩnh vực kết xuất và xử lý ảnh được tăng tốc bằng xử lý song song dữ liệu, từ xử lý tín hiệu chung hoặc mô phỏng vật lý đến tài chính tính toán hoặc sinh học tính toán.

Nguồn

Đọc nâng cao


Một số khía cạnh thú vị

Tôi đã viết phép nhân ma trận C ++ nhanh như Matlab nhưng phải cẩn thận. (Trước khi Matlab sử dụng GPU cho việc này).

Nhận xét từ câu trả lời này .


2
Câu nói cuối cùng đó không phải là một sự thật, đó là sự khoe khoang trống rỗng. Người đó đã nhận được một số yêu cầu về mã kể từ khi anh ta đăng nó. Nhưng không có mã trong tầm nhìn.
Cris Luengo

1
Mô tả của bạn về cách nhanh chóng bạn có thể tính toán trên GPU không giải quyết được câu hỏi nào cả. Chúng ta đều biết rằng 128 lõi nhỏ có thể làm nhiều công việc giống nhau, đơn điệu hơn 2 lõi lớn. Hiện tại, MATLAB cũng có thể sử dụng GPU (đơn vị xử lý đồ họa) cho việc này. Có, nhưng không phải mặc định. Phép nhân ma trận thông thường vẫn sử dụng BLAS.
Cris Luengo

@CrisLuengo, OK, nó không phải là sự thật! Có lẽ bạn có quyền về "khoe khoang" của anh ấy - chúng tôi không biết về điều đó và chúng tôi cũng không biết tại sao anh ấy không trả lời. Đối với nhận xét thứ hai: mô tả các tính toán trên GPU trả lời câu hỏi vì đối với phép nhân ma trận trong đại số tuyến tính, nó sử dụng các phép toán dấu phẩy động. Có thể nó không phải là cho tất cả các peole dễ hiểu, nhưng tôi nghĩ rằng họ phải hiểu những điều cơ bản này. Trong trường hợp khác, họ phải học những điều cơ bản này lúc đầu trước khi họ đọc một số bài viết về ma trận. Và nếu người khác sẽ viết cho tôi về nó thì tôi sẽ thêm chi tiết này. Cảm ơn bạn!
Bharata

@CrisLuengo, tôi đã viết từ này "additionally". Nó có nghĩa là: nó có thể được sử dụng. Điều đó cũng có nghĩa là nhân ma trận bình thường vẫn sử dụng các thư viện phần mềm. Bạn có nghĩ rằng tôi phải thay đổi bài viết của mình để dễ hiểu hơn không? Cảm ơn bạn đã bình luận của bạn!
Bharata
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.