Warum ist MATLAB bei der Matrixmultiplikation so schnell?

190

Ich mache einige Benchmarks mit CUDA, C ++, C #, Java und verwende MATLAB zur Verifizierung und Matrixgenerierung. Wenn ich eine Matrixmultiplikation mit MATLAB durchführe, werden 2048x2048noch größere Matrizen fast sofort multipliziert.

             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

Nur CUDA ist wettbewerbsfähig, aber ich dachte, dass mindestens C ++ etwas eng und nicht 60-mal langsamer sein wird. Ich weiß auch nicht, was ich über die C # -Ergebnisse denken soll. Der Algorithmus ist genau der gleiche wie C ++ und Java, aber es gibt einen riesigen Sprung 2048von 1024.

Wie führt MATLAB die Matrixmultiplikation so schnell durch?

C ++ - Code:

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();
Wolf
quelle
14
Wahrscheinlich ist es eine Frage, welchen Algorithmus Sie verwenden.
Robert J.
24
Stellen Sie sicher, dass Matlab Ihr Ergebnis nicht zwischenspeichert, es ist ein kniffliges Tier. Stellen Sie zunächst sicher, dass die Berechnung tatsächlich durchgeführt wird, und vergleichen Sie dann.
Rubenvb
10
Ich denke tatsächlich, dass dieser Beitrag wirklich interessant ist, aber ich würde wirklich gerne passendere Benchmarks sehen. Ich denke zum Beispiel, dass Matlab R2011a Multithreading automatisch verwendet und Matrixmultiplikationen mithilfe der mkl / blas-Bibliothek von Intel implementiert werden. Daher würde ich vermuten, dass c ++ schneller ist, wenn man einen mkl-Aufruf verwendet, um die Matrixmultiplikation durchzuführen. Die Frage wäre dann, was Matlabs Overhead ist. Ich weiß, dass dies von zusätzlichen Details der Matrixmultiplikation abhängt, aber die obigen Zahlen sind im Moment ziemlich bedeutungslos.
Lucas
1
Sie können den "Strassen-Algorithmus" der Laufzeit O (n ^ 2.81) für eine Multiplikation mit großer quadratischer Matrix verwenden, die etwa 10x schneller ist als die native Multiplikation, die in O (n ^ 3) ausgeführt wird. Auch SSE / AVX kann Ihnen helfen, die Code-Ausführung um das 8-20-fache zu beschleunigen. Alles in allem können Sie eine AC-Implementierung schneller als die des Matlab durchführen.
DU Jiaen

Antworten:

85

Hier sind meine Ergebnisse mit MATLAB R2011a + Parallel Computing Toolbox auf einem Computer mit einem 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 verwendet hochoptimierte Bibliotheken für die Matrixmultiplikation, weshalb die einfache MATLAB-Matrixmultiplikation so schnell ist. Die gpuArrayVersion verwendet MAGMA .

Update mit R2014a auf einem Computer mit einem Tesla K20c und den neuen timeitund gputimeitFunktionen:

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

Update mit R2018b auf einem WIN64-Computer mit 16 physischen Kernen und einem Tesla V100:

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

(NB: Irgendwann (ich vergesse wann genau) wurde gpuArrayvon MAGMA auf cuBLAS umgestellt - MAGMA wird jedoch immer noch für einige gpuArrayOperationen verwendet.)

Edric
quelle
Warum ist das wichtig?
Mad Physicist
Warum ist was wichtig? Ich habe versucht, einen Einblick in die von MATLAB in verschiedenen Situationen verwendeten Bibliotheken zu geben, um zu erklären, warum die Leistung von MATLAB gut ist - dh weil hochoptimierte numerische Bibliotheken verwendet werden.
Edric
175

Diese Art von Frage kommt immer wieder vor und sollte klarer beantwortet werden als "MATLAB verwendet hochoptimierte Bibliotheken" oder "MATLAB verwendet die MKL" einmal bei Stapelüberlauf.

Geschichte:

Die Matrixmultiplikation (zusammen mit der Matrixvektor-, Vektorvektormultiplikation und vielen der Matrixzerlegungen) ist (sind) das wichtigste Problem in der linearen Algebra. Ingenieure haben diese Probleme seit den Anfängen mit Computern gelöst.

Ich bin kein Experte für die Geschichte, aber anscheinend hat damals jeder seine FORTRAN-Version mit einfachen Schleifen umgeschrieben. Dann kam eine gewisse Standardisierung mit der Identifizierung von "Kerneln" (Grundroutinen), die die meisten linearen Algebra-Probleme brauchten, um gelöst zu werden. Diese Grundoperationen wurden dann in einer Spezifikation standardisiert, die als Grundlegende lineare Algebra-Unterprogramme (BLAS) bezeichnet wurde. Ingenieure könnten diese standardmäßigen, gut getesteten BLAS-Routinen dann in ihrem Code aufrufen, was ihre Arbeit erheblich erleichtert.

BLAS:

BLAS entwickelte sich von Level 1 (der ersten Version, die Skalarvektor- und Vektorvektoroperationen definierte) zu Level 2 (Vektormatrixoperationen) zu Level 3 (Matrixmatrixoperationen) und lieferte immer mehr "Kernel", die so standardisiert waren und mehr der grundlegenden linearen Algebraoperationen. Die ursprünglichen FORTRAN 77-Implementierungen sind weiterhin auf der Netlib-Website verfügbar .

Auf dem Weg zu einer besseren Leistung:

Im Laufe der Jahre (insbesondere zwischen den Versionen BLAS Level 1 und Level 2: Anfang der 80er Jahre) änderte sich die Hardware mit dem Aufkommen von Vektoroperationen und Cache-Hierarchien. Diese Entwicklungen ermöglichten es, die Leistung der BLAS-Subroutinen erheblich zu steigern. Verschiedene Anbieter implementierten dann BLAS-Routinen, die immer effizienter wurden.

Ich kenne nicht alle historischen Implementierungen (ich war damals noch nicht geboren oder ein Kind), aber zwei der bemerkenswertesten kamen Anfang der 2000er Jahre heraus: Intel MKL und GotoBLAS. Ihr Matlab verwendet Intel MKL, ein sehr gutes, optimiertes BLAS, und das erklärt die großartige Leistung, die Sie sehen.

Technische Details zur Matrixmultiplikation:

Warum ist Matlab (die MKL) so schnell dgemm(allgemeine Matrix-Matrix-Multiplikation mit doppelter Genauigkeit)? In einfachen Worten: weil es Vektorisierung und gutes Zwischenspeichern von Daten verwendet. In komplexeren Begriffen: siehe den Artikel von Jonathan Moore.

Wenn Sie Ihre Multiplikation in dem von Ihnen bereitgestellten C ++ - Code durchführen, sind Sie grundsätzlich überhaupt nicht cachefreundlich. Da ich vermute, dass Sie ein Array von Zeigern auf Zeilenarrays erstellt haben, sind Ihre Zugriffe in Ihrer inneren Schleife auf die k-te Spalte von "matice2": matice2[m][k]sehr langsam. In der Tat müssen Sie beim Zugriff matice2[0][k]das k-te Element des Arrays 0 Ihrer Matrix erhalten. In der nächsten Iteration müssen Sie dann auf matice2[1][k]das k-te Element eines anderen Arrays (das Array 1) zugreifen . In der nächsten Iteration greifen Sie dann auf ein weiteres Array zu und so weiter ... Da die gesamte Matrix matice2nicht in die höchsten Caches passt (sie ist 8*1024*1024Bytes groß), muss das Programm das gewünschte Element aus dem Hauptspeicher abrufen und dabei viel verlieren Zeit.

Wenn Sie nur die Matrix transponiert hätten, sodass die Zugriffe auf zusammenhängende Speicheradressen erfolgen würden, würde Ihr Code bereits viel schneller ausgeführt, da der Compiler jetzt ganze Zeilen gleichzeitig in den Cache laden kann. Probieren Sie einfach diese modifizierte Version aus:

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

So können Sie sehen, wie nur die Cache-Lokalität die Leistung Ihres Codes erheblich gesteigert hat. Jetzt echtdgemm Implementierungen dies auf einer sehr umfangreichen Ebene: Sie führen die Multiplikation mit Blöcken der Matrix durch, die durch die Größe des TLB definiert sind (Translation Lookaside Buffer, lange Rede, kurzer Sinn: Was kann effektiv zwischengespeichert werden), so dass sie zum Prozessor streamen genau die Datenmenge, die es verarbeiten kann. Der andere Aspekt ist die Vektorisierung. Sie verwenden die vektorisierten Anweisungen des Prozessors für einen optimalen Befehlsdurchsatz, was Sie mit Ihrem plattformübergreifenden C ++ - Code nicht wirklich tun können.

Schließlich sind Leute, die behaupten, es liege am Strassen- oder Coppersmith-Winograd-Algorithmus, falsch. Beide Algorithmen sind aufgrund der oben genannten Hardware-Überlegungen in der Praxis nicht implementierbar.

reverse_engineer
quelle
2
Ich habe gerade ein Video von Scott Meyers über die Bedeutung von Cache-Größen und das Anpassen von Daten an Cache-Zeilengrößen sowie über die Probleme gesehen, die bei Multithread-Lösungen auftreten können, bei denen keine gemeinsamen Daten in der Quelle vorhanden sind, die jedoch auf der Hardware gemeinsam genutzt werden / Core-Thread-Ebene: youtu.be/WDIkqP4JbkE
WillC
40

Deshalb . MATLAB führt keine naive Matrixmultiplikation durch, indem jedes einzelne Element wie in Ihrem C ++ - Code durchlaufen wird.

Natürlich gehe ich davon aus, dass Sie nur C=A*Beine Multiplikationsfunktion verwendet haben, anstatt sie selbst zu schreiben.

Doug Stephen
quelle
19

Matlab hat LAPACK vor einiger Zeit integriert, daher gehe ich davon aus, dass ihre Matrixmultiplikation etwas verwendet, das mindestens so schnell ist. LAPACK-Quellcode und Dokumentation sind sofort verfügbar.

Sie können sich auch Goto und Van De Geijns Artikel "Anatomy of High-Performance Matrix Multiplication" unter http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.140.1785&rep=rep1&type=pdf ansehen

Jonathan Moore
quelle
7
MATLAB verwendet die Intel MKL Library, die eine optimierte Implementierung von BLAS / LAPACK-Routinen bietet: stackoverflow.com/a/16723946/97160
Amro
11

Die Antwort lautet LAPACK und BLAS- Bibliotheken machen MATLAB bei Matrixoperationen unglaublich schnell, nicht irgendeinen proprietären Code von den Leuten bei MATLAB.

Verwenden Sie die LAPACK- und / oder BLAS- Bibliotheken in Ihrem C ++ - Code für Matrixoperationen, und Sie sollten eine ähnliche Leistung wie MATLAB erhalten. Diese Bibliotheken sollten auf jedem modernen System frei verfügbar sein, und Teile wurden über Jahrzehnte in der Wissenschaft entwickelt. Beachten Sie, dass es mehrere Implementierungen gibt, einschließlich einiger geschlossener Quellen wie Intel MKL .

Eine Diskussion darüber, wie BLAS eine hohe Leistung erzielt, finden Sie hier.


Übrigens ist es meiner Erfahrung nach ein schwerer Schmerz, LAPACK-Bibliotheken direkt von c aus aufzurufen (aber es lohnt sich). Sie müssen die Dokumentation SEHR genau lesen.

Matthew Gunn
quelle
8

Wenn Sie eine Matrixmultiplikation durchführen, verwenden Sie eine naive Multiplikationsmethode, die einige Zeit in Anspruch nimmt O(n^3).

Es gibt einen Matrixmultiplikationsalgorithmus, der benötigt O(n^2.4). Dies bedeutet, dass bei n=2000Ihrem Algorithmus ~ 100-mal so viel Rechenaufwand erforderlich ist wie beim besten Algorithmus.
Weitere Informationen zu den effizienten Implementierungsmethoden finden Sie auf der Wikipedia-Seite zur Matrixmultiplikation.

Jouni Osmala
quelle
und MATLAB verwenden wahrscheinlich einen solchen Algorithmus, da die Zeit für die 1024 * 1024-Matrixmultiplikation kleiner als das 8-fache der Zeit für die 2048 * 2048-Matrixmultiplikation ist! Gut gemacht, MATLAB Jungs.
Renaud
4
Ich bezweifle eher, dass sie trotz ihrer theoretischen Vorteile die "effizienten" Multiplikationsalgorithmen verwenden. Selbst Straßens Algorithmus hat Implementierungsschwierigkeiten, und der Coppersmith-Winograd-Algorithmus, über den Sie wahrscheinlich einfach gelesen haben, ist (derzeit) nicht praktikabel. Auch verwandter SO-Thread: stackoverflow.com/questions/17716565/…
Ernir
Dieser Algorithmus ist nur für extrem große Matrizen geeignet.
@Renaud. Das ist die Definition eines relativ konstanten Overheads
Mad Physicist
6

Abhängig von Ihrer Matlab-Version wird Ihre GPU möglicherweise bereits verwendet.

Etwas anderes; Matlab verfolgt viele Eigenschaften Ihrer Matrix. ob seine Diagonale, Hermetian und so weiter, und spezialisiert seine darauf basierenden Algorithmen. Vielleicht ist es auf die Nullmatrix spezialisiert, die Sie übergeben, oder so ähnlich? Vielleicht werden wiederholte Funktionsaufrufe zwischengespeichert, was Ihre Timings durcheinander bringt? Vielleicht optimiert es wiederholte unbenutzte Matrixprodukte?

Verwenden Sie eine Matrix aus Zufallszahlen, um solche Ereignisse zu vermeiden, und stellen Sie sicher, dass Sie die Ausführung erzwingen, indem Sie das Ergebnis auf einen Bildschirm, eine Festplatte oder ähnliches drucken.

Eelco Hoogendoorn
quelle
4
Als starker ML-Benutzer kann ich Ihnen sagen, dass sie GPGPU noch nicht verwenden. Neue Version von matlab Verwenden Sie (endlich) SSE1 / 2. Aber ich habe Tests gemacht. Eine MexFunction, die eine elementweise Multiplikation durchführt, läuft doppelt so schnell wie A.*Bsie. Das OP vermasselt also mit ziemlicher Sicherheit etwas.
KitsuneYMG
6
Matlab mit Parallel Computing Toolbox kann eine CUDA-GPU verwenden, dies ist jedoch explizit: Sie müssen die Daten auf die GPU übertragen.
Edric
Ich benutze M1 = single (rand (1024,1024) * 255); M2 = einfach (Rand (1024, 1024) * 255); und M3 = M1 · M2; ... dann schreibe in eine Binärdatei von Floats, alles ist sehr schnell erledigt.
Wolf
3

MATLAB verwendet eine hochoptimierte Implementierung von LAPACK von Intel, die als Intel Math Kernel Library (Intel MKL) bekannt ist - speziell die dgemm-Funktion . Die Geschwindigkeit Diese Bibliothek nutzt Prozessorfunktionen wie SIMD-Anweisungen und Mehrkernprozessoren. Sie dokumentieren nicht, welchen spezifischen Algorithmus sie verwenden. Wenn Sie Intel MKL von C ++ aus aufrufen, sollten Sie eine ähnliche Leistung sehen.

Ich bin nicht sicher, welche Bibliothek MATLAB für die GPU-Multiplikation verwendet, aber wahrscheinlich so etwas wie nVidia CUBLAS .

gregswiss
quelle
1
Sie haben Recht, aber haben Sie diese Antwort gesehen ? IPP ist jedoch kein MKL und MKL weist im Vergleich zu IPP eine weitaus bessere Leistung der linearen Algebra auf. Außerdem hat IPP in neueren Versionen das Matrix-Mathematik-Modul abgelehnt.
Chappjc
Entschuldigung, ich meinte MKL nicht IPP
Gregswiss
Sie haben Recht, die andere Antwort deckt es ab. Es ist so ausführlich, dass ich es verpasst habe.
Gregswiss
2

Die allgemeine Antwort auf "Warum kann matlab xxx schneller ausführen als andere Programme" lautet, dass matlab viele integrierte, optimierte Funktionen hat.

Die anderen Programme, die häufig verwendet werden, verfügen nicht über diese Funktionen, sodass Benutzer ihre eigenen kreativen Lösungen anwenden, die überraschend langsamer sind als professionell optimierter Code.

Dies kann auf zwei Arten interpretiert werden:

1) Der übliche / theoretische Weg: Matlab ist nicht wesentlich schneller, Sie machen nur den Benchmark falsch

2) Der realistische Weg: Für dieses Zeug ist Matlab in der Praxis schneller, weil Sprachen wie c ++ auf ineffektive Weise einfach zu leicht verwendet werden.

Dennis Jaheruddin
quelle
7
Er vergleicht die MATLAB-Geschwindigkeit mit der Geschwindigkeit einer Funktion, die er in zwei Minuten geschrieben hat. Ich kann eine schnellere Funktion in 10 Minuten oder eine viel schnellere Funktion in zwei Stunden schreiben. Die MATLAB-Leute haben mehr als zwei Stunden damit verbracht, ihre Matrixmultiplikation schnell zu machen.
Gnasher729
2

Der scharfe Kontrast ist nicht nur auf die erstaunliche Optimierung von Matlab zurückzuführen (wie bereits in vielen anderen Antworten erläutert), sondern auch auf die Art und Weise, wie Sie die Matrix als Objekt formuliert haben.

Es scheint, als hätten Sie Matrix zu einer Liste von Listen gemacht? Eine Liste von Listen enthält Zeiger auf Listen, die dann Ihre Matrixelemente enthalten. Die Positionen der enthaltenen Listen werden willkürlich zugewiesen. Während Sie Ihren ersten Index (Zeilennummer?) Durchlaufen, ist die Zeit des Speicherzugriffs sehr wichtig. Warum versuchen Sie im Vergleich nicht, die Matrix mit der folgenden Methode als einzelne Liste / Vektor zu implementieren?

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

Und

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

Der gleiche Multiplikationsalgorithmus sollte verwendet werden, damit die Anzahl der Flops gleich ist. (n ^ 3 für quadratische Matrizen der Größe n)

Ich bitte Sie, die Zeit so festzulegen, dass das Ergebnis mit dem vergleichbar ist, das Sie zuvor hatten (auf demselben Computer). Mit dem Vergleich zeigen Sie genau, wie wichtig die Speicherzugriffszeit sein kann!

Argyll
quelle
2

In C ++ ist es langsam, weil Sie kein Multithreading verwenden. Wenn A = BC ist, wo sie alle Matrizen sind, kann die erste Reihe von A unabhängig von der zweiten Reihe usw. berechnet werden. Wenn A, B und C alle n mal n Matrizen sind, können Sie die Multiplikation um beschleunigen ein Faktor von n ^ 2, as

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

Wenn Sie beispielsweise Eigen [ http://eigen.tuxfamily.org/dox/GettingStarted.html ] verwenden, ist Multithreading integriert und die Anzahl der Threads kann angepasst werden.

wsw
quelle
2

Denn MATLAB ist eine Programmiersprache, die zunächst für die numerische lineare Algebra (Matrixmanipulationen) entwickelt wurde und über Bibliotheken verfügt, die speziell für Matrixmultiplikationen entwickelt wurden. Und jetzt kann MATLAB auch zusätzlich die GPUs (Graphics Processing Unit) verwenden .

Und wenn wir uns Ihre Berechnungsergebnisse ansehen:

             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

dann können wir sehen, dass nicht nur MATLAB bei der Matrixmultiplikation so schnell ist: CUDA C (Programmiersprache von NVIDIA) hat einige bessere Ergebnisse als MATLAB. CUDA C hat auch Bibliotheken, die speziell für Matrixmultiplikationen entwickelt wurden, und verwendet die GPUs.

Kurze Geschichte von MATLAB

Cleve Moler, Vorsitzender des Fachbereichs Informatik an der Universität von New Mexico, begann Ende der 1970er Jahre mit der Entwicklung von MATLAB. Er entwarf es, um seinen Schülern Zugang zu LINPACK (einer Softwarebibliothek zur Durchführung der numerischen linearen Algebra) und EISPACK zu ermöglichen(ist eine Softwarebibliothek zur numerischen Berechnung der linearen Algebra), ohne dass sie Fortran lernen müssen. Es breitete sich bald auf andere Universitäten aus und fand ein starkes Publikum in der Gemeinschaft der angewandten Mathematik. Jack Little, ein Ingenieur, war ihm während eines Besuchs von Moler an der Stanford University im Jahr 1983 ausgesetzt. Er erkannte sein kommerzielles Potenzial und schloss sich Moler und Steve Bangert an. Sie schrieben MATLAB in C um und gründeten MathWorks 1984, um seine Entwicklung fortzusetzen. Diese umgeschriebenen Bibliotheken wurden als JACKPAC bezeichnet. Im Jahr 2000 wurde MATLAB neu geschrieben, um einen neueren Satz von Bibliotheken für die Matrixmanipulation zu verwenden, LAPACK (eine Standardsoftwarebibliothek für numerische lineare Algebra).

Quelle

Was ist CUDA C.

CUDA C verwendet auch Bibliotheken, die speziell für Matrixmultiplikationen wie OpenGL (Open Graphics Library) entwickelt wurden. Es verwendet auch GPU und Direct3D (unter MS Windows).

Die CUDA-Plattform funktioniert mit Programmiersprachen wie C, C ++ und Fortran. Diese Zugänglichkeit erleichtert es Spezialisten für parallele Programmierung, GPU-Ressourcen zu verwenden, im Gegensatz zu früheren APIs wie Direct3D und OpenGL , für die fortgeschrittene Kenntnisse in der Grafikprogrammierung erforderlich waren. Außerdem unterstützt CUDA Programmierframeworks wie OpenACC und OpenCL .

Geben Sie hier die Bildbeschreibung ein

Beispiel für einen CUDA-Verarbeitungsablauf:

  1. Kopieren Sie Daten vom Hauptspeicher in den GPU-Speicher
  2. Die CPU initiiert den GPU-Rechenkern
  3. Die CUDA-Kerne der GPU führen den Kernel parallel aus
  4. Kopieren Sie die resultierenden Daten aus dem GPU-Speicher in den Hauptspeicher

Vergleichen der CPU- und GPU-Ausführungsgeschwindigkeiten

Wir haben einen Benchmark durchgeführt, in dem wir die Zeit gemessen haben, die erforderlich war, um 50 Zeitschritte für Rastergrößen von 64, 128, 512, 1024 und 2048 auf einem Intel Xeon-Prozessor X5650 auszuführen und dann eine NVIDIA Tesla C2050-GPU zu verwenden.

Geben Sie hier die Bildbeschreibung ein

Bei einer Rastergröße von 2048 zeigt der Algorithmus eine 7,5-fache Verkürzung der Rechenzeit von mehr als einer Minute auf der CPU auf weniger als 10 Sekunden auf der GPU. Das Diagramm der Protokollskala zeigt, dass die CPU bei kleinen Rastergrößen tatsächlich schneller ist. Mit der Weiterentwicklung und Reifung der Technologie können GPU-Lösungen jedoch zunehmend kleinere Probleme bewältigen, ein Trend, den wir voraussichtlich fortsetzen werden.

Quelle

Aus der Einführung zum CUDA C-Programmierhandbuch:

Aufgrund der unstillbaren Nachfrage des Marktes nach hochauflösenden 3D-Grafiken in Echtzeit hat sich die programmierbare Grafikprozessoreinheit oder GPU zu einem hochparallelen Multithread-Prozessor mit vielen Kernen entwickelt, der eine enorme Rechenleistung und eine sehr hohe Speicherbandbreite aufweist, wie durch Figure 1und dargestellt Figure 2.

Abbildung 1. Gleitkommaoperationen pro Sekunde für die CPU und die GPU

Geben Sie hier die Bildbeschreibung ein

Abbildung 2 . Speicherbandbreite für CPU und GPU

Geben Sie hier die Bildbeschreibung ein

Der Grund für die Diskrepanz in der Gleitkommafähigkeit zwischen der CPU und der GPU liegt darin, dass die GPU auf rechenintensive, hochparallele Berechnungen spezialisiert ist - genau das, worum es beim Grafik-Rendering geht - und daher so konzipiert ist, dass mehr Transistoren für die Datenverarbeitung vorgesehen sind anstatt Daten-Caching und Flusskontrolle, wie schematisch dargestellt durch Figure 3.

Abbildung 3 . Die GPU widmet der Datenverarbeitung mehr Transistoren

Geben Sie hier die Bildbeschreibung ein

Insbesondere ist die GPU besonders gut geeignet, um Probleme anzugehen, die als datenparallele Berechnungen ausgedrückt werden können - dasselbe Programm wird auf vielen Datenelementen parallel ausgeführt - mit hoher arithmetischer Intensität - dem Verhältnis von arithmetischen Operationen zu Speicheroperationen. Da für jedes Datenelement dasselbe Programm ausgeführt wird, besteht eine geringere Anforderung an eine ausgefeilte Flusssteuerung, und da es für viele Datenelemente ausgeführt wird und eine hohe arithmetische Intensität aufweist, kann die Speicherzugriffslatenz mit Berechnungen anstelle von Big-Data-Caches ausgeblendet werden .

Die datenparallele Verarbeitung ordnet Datenelemente parallel verarbeitenden Threads zu. Viele Anwendungen, die große Datenmengen verarbeiten, können ein datenparalleles Programmiermodell verwenden, um die Berechnungen zu beschleunigen. Beim 3D-Rendering werden große Sätze von Pixeln und Scheitelpunkten parallelen Threads zugeordnet. In ähnlicher Weise können Bild- und Medienverarbeitungsanwendungen wie Nachbearbeitung gerenderter Bilder, Videokodierung und -decodierung, Bildskalierung, Stereovision und Mustererkennung Bildblöcke und Pixel parallel verarbeitenden Threads zuordnen. Tatsächlich werden viele Algorithmen außerhalb des Bereichs der Bildwiedergabe und -verarbeitung durch datenparallele Verarbeitung beschleunigt, von der allgemeinen Signalverarbeitung oder Physiksimulation bis hin zur Computerfinanzierung oder Computerbiologie.

Quelle

Fortgeschrittenes Lesen


Einige interessante Facs

Ich habe eine C ++ - Matrixmultiplikation geschrieben, die genauso schnell ist wie die von Matlab, aber es hat einige Sorgfalt gekostet. (Bevor Matlab dafür GPUs verwendete).

Сitation aus dieser Antwort .

Bharata
quelle
2
Das letzte Zitat ist keine „Tatsache“, es ist leer. Diese Person hat mehrere Anfragen nach Code erhalten, seit sie das gepostet hat. Aber kein Code in Sicht.
Cris Luengo
1
Ihre Beschreibung, wie schnell Sie Berechnungen auf einer GPU durchführen können, beantwortet die Frage überhaupt nicht. Wir alle wissen, dass 128 kleine Kerne mehr von derselben monotonen Arbeit leisten können als 2 große Kerne. "Und jetzt kann MATLAB auch zusätzlich die GPUs (Graphics Processing Unit) verwenden." Ja, aber nicht standardmäßig. Bei der normalen Matrixmultiplikation wird weiterhin BLAS verwendet.
Cris Luengo
@CrisLuengo, OK, das ist keine Tatsache! Vielleicht haben Sie Recht mit seiner "Prahlerei" - wir wissen nichts darüber und wir wissen auch nicht, warum er nicht antwortet. Für den zweiten Kommentar: Die Beschreibung der Berechnungen auf der GPU beantwortet die Frage, da für Matrixmultiplikationen in der linearen Algebra Gleitkommaoperationen verwendet werden. Vielleicht ist es nicht für alle Menschen verständlich, aber ich denke, dass sie diese Grundlagen verstehen müssen. In anderen Fällen müssen sie diese Grundlagen zuerst lernen, bevor sie einen Artikel über Matrizen lesen können. Und wenn mir jemand anderes darüber schreibt, werde ich diese Details hinzufügen. Danke dir!
Bharata
@CrisLuengo, ich habe das Wort geschrieben "additionally". Es bedeutet: es kann verwendet werden. Dies bedeutet auch, dass bei der normalen Matrixmultiplikation weiterhin Softwarebibliotheken verwendet werden. Denkst du, ich muss meinen Beitrag ändern, um verständlicher zu werden? Vielen Dank für Ihre Kommentare!
Bharata