Ich habe gerade eine Nvidia GT660-Grafikkarte auf meinem Desktop installiert und kann sie nach einiger Anstrengung mit R verbinden.
Ich habe mit mehreren R-Paketen gespielt, die GPUs verwenden, insbesondere Gputools, und ich habe die Zeit verglichen, die GPU und CPU für einige grundlegende Vorgänge benötigt haben:
- Matrizen invertieren (CPU schneller)
- qr Zerlegung (CPU schneller)
- große Korrelationsmatrizen (CPU schneller)
- Matrixmultiplikation (GPU viel schneller!)
Beachten Sie, dass ich hauptsächlich mit gputools experimentiert habe, damit andere Pakete möglicherweise eine bessere Leistung erzielen.
In groben Zügen lautet meine Frage: Welche statistischen Routineoperationen sollten auf einer GPU und nicht auf einer CPU ausgeführt werden?
Antworten:
GPUs sind empfindliche Tiere. Obwohl die beste Nvidia-Karte theoretisch alle aufgeführten Vorgänge 100-mal schneller als die schnellste CPU ausführen kann, können etwa eine Million Dinge dieser Beschleunigung im Wege stehen. Jeder Teil des relevanten Algorithmus und des Programms, in dem er ausgeführt wird, muss ausgiebig optimiert und optimiert werden, um diese theoretische Höchstgeschwindigkeit zu erreichen. Es ist allgemein nicht bekannt, dass R eine besonders schnelle Sprache ist, und daher wundert es mich nicht, dass die Standard-GPU-Implementierung nicht so gut ist, zumindest was die Leistung angeht. Die R-GPU-Funktionen verfügen jedoch möglicherweise über Optimierungseinstellungen, die Sie optimieren können, um einen Teil der fehlenden Leistung wiederherzustellen.
Wenn Sie sich mit GPUs befassen, weil Sie festgestellt haben, dass einige Berechnungen, die Sie ausführen müssen, Wochen / Monate in Anspruch nehmen werden, lohnt es sich möglicherweise, von R auf eine leistungsfreundlichere Sprache zu migrieren. Die Arbeit mit Python ist nicht allzu schwierig als mit R. Die NumPy- und SciPy-Pakete haben die gleichen stat-Funktionen wie R, und PyCuda kann verwendet werden, um Ihre eigenen GPU-basierten Funktionen auf relativ einfache Weise zu implementieren.
Wenn Sie wirklich die Geschwindigkeit erhöhen möchten, mit der Ihre Funktionen auf GPUs ausgeführt werden, würde ich in Betracht ziehen, Ihre eigenen Funktionen in einer Kombination aus C ++ und CUDA zu implementieren. Die CUBLAS-Bibliothek kann verwendet werden, um alle mit der linearen Algebra zusammenhängenden schweren Lasten zu bewältigen. Bedenken Sie jedoch, dass das Schreiben eines solchen Codes eine Weile dauern kann (insbesondere, wenn Sie ihn zum ersten Mal ausführen). Daher sollte dieser Ansatz nur für die Berechnungen reserviert werden, deren Ausführung extrem lange dauert (Monate) und / oder dass du es hunderte Male wiederholen wirst.
quelle
Allgemein ausgedrückt sind Algorithmen, die auf der GPU schneller ausgeführt werden, solche, bei denen Sie denselben Befehlstyp für viele verschiedene Datenpunkte ausführen.
Ein einfaches Beispiel, um dies zu veranschaulichen, ist die Matrixmultiplikation.
Angenommen, wir führen die Matrixberechnung durch
Ein einfacher CPU-Algorithmus könnte ungefähr so aussehen
// beginnend mit C = 0
Das Wichtigste dabei ist, dass es viele verschachtelte for-Schleifen gibt und jeder Schritt nach dem anderen ausgeführt werden muss.
Siehe ein Diagramm dazu
Beachten Sie, dass die Berechnung jedes Elements von C von keinem der anderen Elemente abhängt. Es spielt also keine Rolle, in welcher Reihenfolge die Berechnungen durchgeführt werden.
Auf der GPU können diese Vorgänge also gleichzeitig ausgeführt werden.
Ein GPU-Kernel zum Berechnen einer Matrixmultiplikation würde ungefähr so aussehen
Dieser Kernel hat nur die beiden inneren for-Schleifen. Ein Programm, das diesen Job an die GPU sendet, weist die GPU an, diesen Kernel für jeden Datenpunkt in C auszuführen. Die GPU führt diese Anweisungen für viele Threads gleichzeitig aus. Genau wie das alte Sprichwort "Billiger im Dutzend", sind GPUs so konzipiert, dass sie oft schneller das Gleiche tun.
Es gibt jedoch einige Algorithmen, die die GPU verlangsamen. Einige sind für die GPU nicht gut geeignet.
Wenn zum Beispiel Datenabhängigkeiten bestünden, dh: Stellen Sie sich die Berechnung jedes Elements von C in Abhängigkeit von den vorherigen Elementen vor. Der Programmierer müsste eine Barriere in den Kernel einbauen, um zu warten, bis die vorherige Berechnung abgeschlossen ist. Dies wäre eine erhebliche Verlangsamung.
Auch Algorithmen, die viel Verzweigungslogik haben, dh:
neigen dazu, langsamer auf der GPU zu laufen, da die GPU nicht mehr in jedem Thread dasselbe tut.
Dies ist eine vereinfachte Erklärung, da viele andere Faktoren zu berücksichtigen sind. Das Senden von Daten zwischen der CPU und der GPU ist beispielsweise auch zeitaufwändig. Manchmal lohnt es sich, eine Berechnung auf der GPU durchzuführen, auch wenn diese auf der CPU schneller ist, um die zusätzliche Sendezeit zu vermeiden (und umgekehrt).
Viele moderne CPUs unterstützen jetzt auch Parallelität mit Multicore-Prozessoren mit Hyperthreading.
GPUs scheinen auch nicht so gut für Rekursionen zu sein, siehe hier, was wahrscheinlich einige der Probleme mit dem QR-Algorithmus erklärt. Ich glaube, dass man einige rekursive Datenabhängigkeiten hat.
quelle
Ich vermute, dass die meisten statistischen Operationen, die die meiste Zeit in der dichten linearen Algebra verbringen (BLAS, Lapack-Funktionalität), effizient auf der GPU implementiert werden können.
quelle
Mehrere Imputationsmethoden für fehlende Daten? Wie bei Alice-II (R).
Ich denke, diese sind oft peinlich parallel und daher für eine GPU-Architektur geeignet. Ich habe es aber nie selbst ausprobiert.
quelle