PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Warum haben GPUs eigentlich eine hohe Speicherlatenz?


Senior Sanchez
2010-06-19, 11:45:07
Hallo,

Ich beschäftige mich gerade mit GPGPU und dort liest man immer wieder den Satz, dass GPUs versuchen durch die massive Parallelisierung die hohen Speicherlatenzen zu überdecken. Allerdings ist nirgendwo erwähnt, warum die Speicherlatenzen eigentlich so hoch sind.

Ich weiß bisher, dass GPUs ja eine recht hohe Speicherbandbreite haben und sie somit zumindest große Datenblöcke sehr schnell aus ihrem Speicher verarbeiten können. Allerdings soll das Laden kleinerer Datenmengen ineffizient sein, da eine hohe Latenz vorherrscht und es somit relativ lang dauert diese Daten zu laden.

Liegt es einfach am verwendeten GDDR5 Speicher der zwar hohe Taktraten aufweist (damit schnelles Übertragen von großen Mengen), aber auch hohe Latenzen besitzt? Oder steckt da noch etwas anderes dahinter?

Kann mir das jemand erklären?

Danke

Gast
2010-06-19, 11:58:20
Ich denke es liegt hauptsächlich an den sehr kleinen Caches.
Cpus haben sehr große Caches, wodurch Sie Ihre hohen Latenzen zum Arbeitsspeicher überbrücken können.
Wenn man mal vergleicht wie viel Cache ein i7 Rechenwerk verglichen mit einem rv870 RW hat, sieht man schnell dass schon mitellmäßig große Threads regen Arbeitsspeicherzugriff benötigen, währen der i7 noch bequem aus dem sehr schnellen Cache liest.

Der GDDR5 hat zwar sehr hohe per Clock- Latenz, aber Das dürfte er durch die sehr hohe Taktrate gegenüber dem DDR wieder gut machen.

Senior Sanchez
2010-06-19, 12:06:31
Hmm, das wäre natürlich eine Idee.

Das Witzige ist, dass ich parallel auch gerade über FPGAs lese und manche Hersteller preisen ihren FPGA-Ansatz für die Lösung des "von-Neumann I/O Bottleneck" an. Kurz gesagt, sie erklären Register und Caches für böse und preisen den direkten Speicherzugriff per FPGA als Lösung an.

Gast
2010-06-19, 12:19:41
Zugriff auf den Arbeitsspeicher dauert immer länger als auf Caches oder gar Register.
Meist gilt Register>Cache>>Arbeitsspeicher>>Arbeitsspeicher des Hostsystems(bei Grafikkarten)>>>...>>>Platte.
Wie man ohne Register oder Caches schneller als mit sein will, kann ich mir nicht vorstellen.

Senior Sanchez
2010-06-19, 12:39:56
Zugriff auf den Arbeitsspeicher dauert immer länger als auf Caches oder gar Register.
Meist gilt Register>Cache>>Arbeitsspeicher>>Arbeitsspeicher des Hostsystems(bei Grafikkarten)>>>...>>>Platte.
Wie man ohne Register oder Caches schneller als mit sein will, kann ich mir nicht vorstellen.

Genau das sage ich mir auch.
Andererseits glaube ich, dass diese Firma trickst. FPGAs sind schon sehr schnell, allerdings nutzen sie meiner Ansicht nach den Speicher (wir sprechen von bis zu 300 GB) als extrem großen voll-assoziativen Cache. Aber selbst der sollte um Größenordnungen langsamer sein als Register.

Gast
2010-06-19, 12:44:34
Hallo,

Ich beschäftige mich gerade mit GPGPU und dort liest man immer wieder den Satz, dass GPUs versuchen durch die massive Parallelisierung die hohen Speicherlatenzen zu überdecken. Allerdings ist nirgendwo erwähnt, warum die Speicherlatenzen eigentlich so hoch sind.




Dabei geht es nicht nur um Speicherlatenzen sondern in erster Linie um Ausführungslatenzen.

Eine ALU kann zwar pro Takt einen Befehl annehmen und einen ausgeben, das ist aber nicht der gleiche Befehl. Jeder Befehl wird nämlich in einer Pipeline abgearbeitet und bis dieser Fertig ist dauert es einige Takte. Wenn im gleichen Thread ein Befehl ein Ergebnis aus einem vorherigen Befehl bräuchte müsste gewartet werden bis dieses auch Verfügbar ist.

Die GPU versucht das einfach zu überdecken, indem dazwischen einfach Befehle aus anderen Threads eingeschoben werden, die davon unabhängig sind.

Um die Masse an Recheneinheiten auszulasten müssen deshalb ständig 1000e Threads in der GPU in Bearbeitung sein.

Der typische (lesende) Speicherzugriff einer GPU ist auch ein Texturzugriff, und dieser ist typischerweise auch kein einfacher "hol einen Wert aus dem Speicher und benutze ihn"-Zugriff sondern muss erst gefiltert werden, auch das braucht seine Zeit und erhöht damit natürlich die Latenz.

Senior Sanchez
2010-06-19, 13:00:47
Aaaah, ja, das macht Sinn.
Es liegt einfach an der Pipeline Architektur und dank großen Caches erleiden CPUs dieses Problem nicht so extrem wie GPUs, richtig?

Nighthawk13
2010-06-19, 13:21:29
Die ganze GPU-Architektur ist auf Durchsatz ausgelegt.
Die Latenz von 400-800 Zyklen hört sich vielleicht abschreckend an, tatsächlich aber reduziert es die Gesamtleistung des Systems nicht, solange der Code genug Rechenoperationen(im Verhältnis zu Speicherzugriffen) aufweist, um während der Latenzzeit eines Threads die Rechenoperationen der anderen Threads auszuführen.

Auf der CPU hingegen kostet jeder Cycle Latenz Leistung, weil die Ausführung seriell ist und die Rechenwerke während der Wartezeit ungenutzt stillstehen.
Deshalb gibts es auch Out-of-Order-Execution und grosse Caches, um die Latenz zu minimieren.
(Hyperthreading ist eher ein Ansatz, wie ihn die GPU verfolgt: Wenn Thread A stallt, führe Thread B aus).

Senior Sanchez
2010-06-19, 13:30:32
Die ganze GPU-Architektur ist auf Durchsatz ausgelegt.
Die Latenz von 400-800 Zyklen hört sich vielleicht abschreckend an, tatsächlich aber reduziert es die Gesamtleistung des Systems nicht, solange der Code genug Rechenoperationen(im Verhältnis zu Speicherzugriffen) aufweist, um während der Latenzzeit eines Threads die Rechenoperationen der anderen Threads auszuführen.

Auf der CPU hingegen kostet jeder Cycle Latenz Leistung, weil die Ausführung seriell ist und die Rechenwerke während der Wartezeit ungenutzt stillstehen.
Deshalb gibts es auch Out-of-Order-Execution und grosse Caches, um die Latenz zu minimieren.
(Hyperthreading ist eher ein Ansatz, wie ihn die GPU verfolgt: Wenn Thread A stallt, führe Thread B aus).

Das ist mir klar, das weiß ich alles. In dem Thread geht es eher darum, woher eben diese hohen Latenzen kommen. Aber sofern ich das jetzt richtig verstanden habe, sind das typische Latenzen. CPU und GPU versuchen nur auf teilweise unterschiedlichen Wegen, diese zu umgehen.

Nighthawk13
2010-06-19, 14:33:11
Das ist mir klar, das weiß ich alles. In dem Thread geht es eher darum, woher eben diese hohen Latenzen kommen. Aber sofern ich das jetzt richtig verstanden habe, sind das typische Latenzen. CPU und GPU versuchen nur auf teilweise unterschiedlichen Wegen, diese zu umgehen.

Die Speicherlatenzen bei CPUs sind schon deutlich niedriger, auch ohne Cache. Gut 100 Zyklen für Nehalem: http://www.anandtech.com/show/2658/4
Vs. den genannten 400-800 Zyklen bei GPUs(wo jeder Zyklus durch halben Takt auch noch doppelt so lange dauert).

Eine Ursache für die GPU-Speicherlatenz könnte der Scatter/Gather Support sein: Der Memorycontroller muss komplexer dafür sein.

Senior Sanchez
2010-06-19, 14:54:28
Die Speicherlatenzen bei CPUs sind schon deutlich niedriger, auch ohne Cache. Gut 100 Zyklen für Nehalem: http://www.anandtech.com/show/2658/4
Vs. den genannten 400-800 Zyklen bei GPUs(wo jeder Zyklus durch halben Takt auch noch doppelt so lange dauert).

Eine Ursache für die GPU-Speicherlatenz könnte der Scatter/Gather Support sein: Der Memorycontroller muss komplexer dafür sein.

Ah, danke für die Erläuterung.
Das macht genauso Sinn.

Gast
2010-06-19, 16:39:13
Es liegt einfach an der Pipeline Architektur und dank großen Caches erleiden CPUs dieses Problem nicht so extrem wie GPUs, richtig?

Mit den Caches hat das eher weniger zu tun. Die Architekturen von CPU und GPU sind einfach total unterschiedlich. Zwar gibt es bei superskalaren CPUs auch parallele Ausführung, diese ist gegenüber GPUs sehr gering. In GPUs werden 100e Instruktionen parallel ausgeführt, in einem CPU-Kern höchstens eine Hand voll.

Um eine CPU möglichst gut auszulasten werden die Instruktionen eines Threads so angeordnet, dass zwischen 2 abhängigen Instruktionen nach Möglichkeit genügend andere davon unabhängige Instruktionen ausgeführt werden um die Latenzen zu überbrücken. Bekanntermaßen haben ja auch CPUs Pipelines, so dass das Ergebnis einer Instruktion nicht schon im nächsten Takt vorhanden ist, wobei die meisten CPUs auch eine Art von Forwarding unterstützen, wodurch das Ergebnis für die nächste Instruktion schon vor dem kompletten Durchlaufen der Pipeline zur Verfügung steht.
Moderne CPU-Architekturen beherrschen auch out-of-order-execution, sie müssen die Befehle also nicht in der Reihenfolge ausführen, in der sie im Programm stehen, am Ende der Ausführung muss nur sichergestellt sein, dass das Ergebnis identisch ist, als wäre es in der vorgegebenen Reihenfolge ausgeführt worden. Die CPU hat im Prinzip ein bestimmtes Instruktionsfenster und falls eine Instruktion noch nicht gestartet werden kann weil irgendwelche Daten noch nicht verfügbar sind wird einfach die nächste gestartet usw. Das funktioniert so lange im Instruktionsfenster zumindest eine Instruktion vorhanden ist, die gestartet werden kann.

Bei GPUs funktioniert das nicht, die muss die Befehle in der vorgegebenen Reihenfolge ausführen. Bei typischen Aufgaben einer GPU hat man auch nicht genug unabhängige Instruktionen um diese vom Compiler so anzuordnen, dass es zu keinen Stalls kommt. Also lässt man 1000e Threads irgendwo in der GPU herumschwirren und führt gerade diejenigen aus, für die alle Inputdaten vorhanden sind. Der Vergleich mit Hyperthreading ist eigentlich sehr gut, bei der CPU werden eben nur 2 Threads gleichzeitig in Warteschleife gehalten.

Die großen Caches in CPUs sind eigentlich mehr eine Notlösung um mit den Transistoren noch irgendwas sinnvolles zu machen, eine höhere Parallelität innerhalb eines CPU-Kerns würden nämlich kaum etwas bringen, da man dann auch mit OOOE nicht genügend unabhängige Befehle finden würde um diese auch Parallel auszuführen. Man könnte natürlich Hyperthreading weiter ausbauen und noch mehr Threads pro CPU parallel ausführen, allerdings hat man bei üblichen CPU-Aufgaben einfach nicht genügend Threads, dass das ganze sinnvoll wäre.

Coda
2010-06-20, 16:50:22
Die Speicherlatenz wird in GPUs schlicht durch die massive Anzahl an Threads versteckt. Aus der "Sicht" eines einzelnen Thread sind die Latenzen in vielen Fällen dadurch praktisch völlig vernachlässigbar.

Das gleiche Prinzip bei einer CPU findet sich auch in Suns Niagara (UltraSPARC T)

Die Latenz von 400-800 Zyklen hört sich vielleicht abschreckend an, tatsächlich aber reduziert es die Gesamtleistung des Systems nicht, solange der Code genug Rechenoperationen(im Verhältnis zu Speicherzugriffen) aufweist, um während der Latenzzeit eines Threads die Rechenoperationen der anderen Threads auszuführen.
Mit genügend Threads geht das auch mit fast keinen Rechenoperationen - wobei das natürlich hilft.