Wann sollte ich die Arbeit auf eine GPU anstatt auf die CPU verlagern?

15

Neuere Systeme wie OpenCL werden entwickelt, damit wir immer mehr Code auf unseren Grafikprozessoren ausführen können. Dies ist sinnvoll, da wir in der Lage sein sollten, so viel Energie wie möglich in unseren Systemen zu verbrauchen.

Bei all diesen neuen Systemen sieht es jedoch so aus, als wären GPUs in jeder Hinsicht besser als CPUs . Da GPUs parallele Berechnungen durchführen können, scheinen Multi-Core-GPUs tatsächlich viel besser zu sein als Multi-Core-CPUs. Sie würden in der Lage sein, viele Berechnungen gleichzeitig durchzuführen und die Geschwindigkeit wirklich zu verbessern. Gibt es immer noch bestimmte Fälle, in denen die serielle Verarbeitung immer noch besser, schneller und / oder effizienter als die parallele ist?

RétroX
quelle
6
Keine wirkliche Frage zu Hardware. Sollte umformuliert werden auf "wenn die CPU (s) besser programmiert sind als die GPU (s)" und ist so eine ziemlich gute Frage p.se IMO. Siehe das GPGPU-Tag unter anderem auf SO. Aber Fragen zur Architektur "Welche Technologie ist zu verwenden?" Sind hier besser als dort.
Kate Gregory
1
@Kate Dieser Winkel scheint in der verknüpften Super User-Frage sehr gut abgedeckt zu sein. Ich bin ein bisschen überrascht, dass es nicht hierher migriert wurde, um ehrlich zu sein. Es gibt auch das auf SO. Ich werde die Frage erneut eröffnen (da Sie Recht haben, sind die Programmieraspekte hier zum Thema). Ich hoffe, wir sehen eine Antwort, die nicht nur auf eine bestehende (ausgezeichnete) Abdeckung dieses Problems hinweist.
Adam Lear
1
Zu @ Annas Punkt, ich denke, die Antworten müssen viel mehr darüber sein, wann ein Programmierer die GPU verwenden sollte, als eine rein theoretische Diskussion, was der Unterschied zwischen einer GPU und einer CPU ist. Ich habe den Titel bearbeitet, um dies widerzuspiegeln.
2
@RetroX Wir können Fragen nicht als Duplikate schließen, wenn sie sich auf verschiedenen Websites befinden.
Adam Lear

Antworten:

26

Bei all diesen neuen Systemen sieht es jedoch so aus, als wären GPUs in jeder Hinsicht besser als CPUs.

Dies ist ein grundlegendes Missverständnis. Gegenwärtige GPU-Kerne sind im Vergleich zu aktuellen Top-Line-CPUs immer noch begrenzt. Ich denke, die Fermi-Architektur von NVIDIA ist die derzeit leistungsstärkste GPU. Es hat nur 32-Bit-Register für Ganzzahl-Arithmetik und weniger Möglichkeiten für Verzweigungsvorhersage und spekulative Ausführung als ein gängiger Intel-Prozessor. Intel i7-Chips bieten drei Cache-Ebenen, Fermi-Kerne haben nur zwei und jeder Cache auf dem Fermi ist kleiner als der entsprechende Cache auf dem i7. Die Interprozesskommunikation zwischen den GPU-Kernen ist ziemlich begrenzt, und Ihre Berechnungen müssen strukturiert werden, um diese Einschränkung auszugleichen (die Kerne sind in Blöcke unterteilt, und die Kommunikation zwischen Kernen in einem Block ist relativ schnell, die Kommunikation zwischen Blöcken ist jedoch langsam).

Eine wesentliche Einschränkung der aktuellen GPUs besteht darin, dass auf allen Kernen derselbe Code ausgeführt werden muss. Im Gegensatz zu den Kernen in Ihrer CPU können Sie nicht festlegen, dass ein GPU-Kern Ihren E-Mail-Client und ein anderer Kern Ihren Webserver ausführt. Sie geben der GPU die Funktion zum Invertieren einer Matrix, und alle Kerne führen diese Funktion für verschiedene Datenbits aus.

Die Prozessoren der GPU leben in einer isolierten Welt. Sie können das Display steuern, haben jedoch keinen Zugriff auf die Festplatte, das Netzwerk oder die Tastatur.

Der Zugriff auf das GPU-System ist mit erheblichen Gemeinkosten verbunden. Die GPU verfügt über einen eigenen Speicher, sodass Ihre Berechnungen auf die Größe des Speichers auf der GPU-Karte beschränkt sind. Das Übertragen von Daten zwischen dem GPU-Speicher und dem Hauptspeicher ist relativ teuer. Pragmatisch bedeutet dies, dass es keinen Vorteil bringt, eine Handvoll kurzer Berechnungen von der CPU an die GPU zu übergeben, da die Kosten für Einrichtung und Herunterfahren die für die Berechnung erforderliche Zeit übersteigen.

Die Quintessenz ist, dass GPUs nützlich sind, wenn Sie viele (z. B. Hunderte oder Tausende) Kopien einer langen Berechnung haben, die parallel berechnet werden können. Typische Aufgaben, für die dies häufig ist, sind wissenschaftliches Rechnen, Videokodierung und Bildwiedergabe. Für eine Anwendung wie einen Texteditor ist die einzige Funktion, bei der eine GPU nützlich sein kann, das Rendern des Typs auf dem Bildschirm.

Charles E. Grant
quelle
Double Precision Support ist Teil von Shader Model 5 und AMD / ATI hat es auch.
Ben Voigt
@Ben, danke für die Korrektur. Ich habe die falsche Aussage entfernt.
Charles E. Grant
11

GPUs sind keine generalistischen Prozessoren wie CPUs. Sie haben sich darauf spezialisiert, eine ganz bestimmte Sache zu tun - den gleichen Code auf eine große Datenmenge anzuwenden - und das sehr, sehr gut, viel besser als eine CPU. Bei den meisten Anwendungen geht es jedoch nicht darum, den gleichen Code auf eine große Datenmenge anzuwenden. Es handelt sich um eine Ereignisschleife: Warten auf Eingaben, Lesen der Eingaben, Einwirken auf Eingaben und Warten auf weitere Eingaben. Das ist ein ziemlich serieller Prozess, und GPUs saugen an "seriell".

Wenn Sie über eine große Datenmenge verfügen, die Sie verarbeiten müssen, und jedes Element unabhängig von den anderen parallel verarbeitet werden kann, senden Sie es an die GPU. Aber denken Sie nicht an das "neue Paradigma", in das alles hineingezwängt werden muss.

Diese Frage ist mit "Optimierung" gekennzeichnet. Vergessen Sie nicht, sie als eine Frage zu behandeln. Anwenden der GPU-Optimierung, wenn Tests und Profilerstellung ergeben, dass eine Optimierung erforderlich ist und die Aufgabe so beschaffen ist, dass die GPU-Optimierung angewendet werden kann. Andernfalls stören Sie sich nicht daran, da dies eine verfrühte oder inkorrekte Optimierung wäre, die mehr Probleme verursacht, als sie behebt.

Mason Wheeler
quelle
8

Die einfache Antwort ist, dass eine GPU am besten funktioniert, wenn Sie eine ziemlich kleine, ziemlich einfache Berechnung für jede sehr große Anzahl von Elementen durchführen müssen. Um auf diese Weise viel zu erreichen, muss die Berechnung für jedes Element unabhängig von den Berechnungen für die anderen Elemente sein. Wenn es (normalerweise) Abhängigkeiten zwischen einem Element und einem anderen gibt, müssen Sie im Allgemeinen herausfinden, wie Sie es auflösen können, bevor Sie den Code auf der GPU ausführen können. Wenn die Abhängigkeit überhaupt nicht unterbrochen werden kann oder zu viel Arbeit erfordert, wird der Code möglicherweise schneller auf der CPU ausgeführt.

Die meisten aktuellen CPUs unterstützen auch einige Arten von Vorgängen, die von aktuellen GPUs einfach nicht unterstützt werden (z. B. Speicherschutz für Multitasking).

Aus einer etwas anderen Perspektive betrachtet, wurden CPUs (größtenteils) so entwickelt, dass sie für Programmierer einigermaßen praktisch sind, und die Hardware-Leute haben ihr Bestes gegeben (und es ist verdammt gut, dass es das Beste ist!), Um Hardware zu entwickeln, die dieses praktische Modell beibehält der Programmierer, aber immer noch so schnell wie möglich ausgeführt.

GPUs kommen aus einer eher entgegengesetzten Richtung: Sie wurden größtenteils so entworfen, dass sie für den Hardware-Designer bequem sind, und Dinge wie OpenCL haben versucht, ein Programmiermodell so angemessen wie möglich angesichts der Einschränkungen der Hardware bereitzustellen.

Das Schreiben von Code für die Ausführung auf einer GPU nimmt in der Regel mehr Zeit und Mühe in Anspruch (kostet also mehr) als das Gleiche für die CPU. Insofern ist dies in erster Linie dann sinnvoll, wenn:

  1. Das Problem ist so parallel, dass Sie mit minimalem Aufwand einen großen Gewinn erwarten können, oder
  2. Der Geschwindigkeitszuwachs ist so wichtig, dass er viel zusätzliche Arbeit rechtfertigt.

Es gibt einige offensichtliche Möglichkeiten für jede - aber eine große Anzahl von Anwendungen kommt eindeutig keiner von beiden nahe. Ich wäre ziemlich überrascht, wenn (zum Beispiel) bald eine CRUD-Anwendung auf einer GPU laufen würde (und wenn dies der Fall ist, wird dies wahrscheinlich geschehen, weil jemand genau dieses Ziel verfolgt und sich nicht unbedingt einem Optimum nähert Kosten-Nutzen-Verhältnis).

Die Realität ist, dass für viele (ich bin versucht, "die meisten" zu sagen) Anwendungen eine typische CPU weit mehr als schnell genug ist und der Programmierkomfort (der zu Dingen wie der einfacheren Entwicklung neuer Funktionen führt) viel wichtiger ist als Ausführungsgeschwindigkeit.

Jerry Sarg
quelle
3

Sie könnten viele Berechnungen gleichzeitig durchführen und die Geschwindigkeit erheblich verbessern.

Geschwindigkeit verbessern? Na und? Im letzten Jahr kann ich mich nur ein- oder zweimal daran erinnern, wann es gebraucht wurde. Die meiste Zeit wurde ich gebeten, die Logik zu ändern oder zu korrigieren, mich auf eine andere Datenquelle einzustellen, die Benutzerinteraktion usw. zu verbessern. Die einzige Geschwindigkeit, die Kunden an diesen Fällen interessiert waren, war die Geschwindigkeit, mit der Änderungen vorgenommen wurden. Msgstr "Bitte veröffentlichen Sie ein neues Feature in einem Monat oder noch besser in zwei Wochen."

Verstehen Sie mich nicht falsch - als Programmierer drücke ich gerne CPU-Ticks gründlich aus. Es ist nur so, dass diese Kunst normalerweise nicht sehr gefragt ist.

Gibt es immer noch bestimmte Fälle, in denen die serielle Verarbeitung immer noch besser, schneller und / oder effizienter als die parallele ist?

Ich würde sagen, es gibt viele Fälle. Die serielle Verarbeitung ist einfacher als die parallele, was sie in allen Fällen effizienter macht, in denen Geschwindigkeit keine entscheidende Voraussetzung ist. Die serielle Verarbeitung ermöglicht eine einfachere Implementierung von komplizierter Logik und Benutzeroberfläche, es ist einfacher zu spezifizieren und zu testen, zu warten und zu ändern.

In der Regel ermöglicht die serielle Verarbeitung eine klarere Darstellung der Programmierabsicht und ein einfacheres Lesen von Code. Ich würde sagen, es schont die wertvollste und knappste Ressource - das Gehirn des Programmierers.

Mücke
quelle
2

CPUs sind noch vielseitiger. Beispielsweise sind GPUs effizienter als CPUs mit einfacher Genauigkeit, jedoch nicht mit doppelter Genauigkeit. Es gibt viel mehr Bibliotheken für CPUs als für GPUs.

quant_dev
quelle
3
Können Sie etwas näher darauf eingehen? Sie haben drei Aussagen ohne Angaben oder Erklärungen zu deren Richtigkeit gemacht.
Das Fehlen effizienter Berechnungen mit doppelter Genauigkeit ist allgemein bekannt: en.wikipedia.org/wiki/GPGPU
quant_dev
@quant: Ihre Informationen sind mindestens 2 Jahre alt: 544 GigaFLOPS ist viel schneller als jede Mainstream-CPU.
Ben Voigt
@Ben Ich verstehe nicht, wo in Ihrem Link die Leistung mit doppelter Genauigkeit erwähnt wird.
quant_dev
@quant: awurl.com/Tt7LAX8lH
Ben Voigt
2

Die einfache Regel lautet: Wenn das, was Sie tun, in Form von Konstrukten aus linearer Algebra formuliert werden kann und zeitkritisch ist, tun Sie dies auf der GPU, andernfalls verwenden Sie die CPU.

GPUs sind nicht wie eine große Anzahl von CPUs, sie weisen stark unterschiedliche Leistungseigenschaften auf.

dan_waterworth
quelle
Wenn es "zeitkritisch" ist, haben Sie wahrscheinlich keine Zeit, die GPU für einen Compute-Shader neu zu konfigurieren und die Daten hochzuladen. Es sind große Probleme, die am meisten profitieren.
Ben Voigt
@Ben, ich denke, wir haben unterschiedliche Definitionen von "zeitkritisch". Ich meine, dass die Berechnung für einen beträchtlichen Zeitraum auf dem kritischen Pfad ist.
Dan_waterworth
1

Wenn Sie nur nach Zahlen suchen, sind GPUs die richtige Wahl. Alle diese ALUs bedeuten jedoch, dass weniger Transistoren für die Steuerung von Fluss- (Verzweigungs-) Schaltungen vorgesehen sind. Wenn Sie also etwas schreiben müssen, das viel komplexen Steuerungsfluss, viele Bedingungen usw. erfordert, ist eine CPU schneller.

Alex
quelle