2016-06-20 25 views
1

Auf einer modernen GPU (sagen wir Kepler), wenn ich 4 unabhängige globale Speicherlesevorgänge (keine Abhängigkeiten zwischen Lesevorgängen) von einem einzigen Thread habe, werden alle 4 Lesevorgänge gleichzeitig pipelineed, so dass ich nur die Latenz Strafe von bezahlen ein einzelner globaler Speicher gelesen? Was ist mit geteiltem Speicher? Wie viele Lesevorgänge können gleichzeitig in der Pipeline sein, ist dies irgendwo dokumentiert?Wie viele gleichzeitige Leseanweisungen pro Thread auf moderner GPU?

+0

Wahrscheinlich gleich einer von den Speichersteuerungen der GPU. Wie 64 Bit oder 2 Floats aber Float2 wäre einfacher für Compiler. –

Antwort

1

Die GPU-Threads funktionieren nicht auf diese Weise. Das Lesen mehrerer globaler Speicher aus einem einzelnen Thread wird niemals kombiniert. Mehrere globale Speicherlesevorgänge aus verschiedenen Threads können jedoch kombiniert werden, wenn sie gleichzeitig gestartet werden und die Positionen, die sie lesen, innerhalb von 128 Byte liegen. Dies geschieht in einem Warp (eine Gruppe von Threads, die immer denselben Befehl ausführen). Zum Beispiel, wenn Thread 0 ~ 31 in einem Warp input[0~31] des Typs float lesen. Alle diese Lesevorgänge werden zu einer Speichertransaktion kombiniert (vorausgesetzt, die Daten sind richtig ausgerichtet). Aber wenn Thread 0 ~ 31 in einem Warp input[0,2,4,...,62] gelesen wird, werden diese Lesevorgänge in zwei Speichertransaktionen kombiniert und die Hälfte der Daten wird gelesen und abgebrochen.

Für gemeinsam genutzten Speicher ist die Latenz ~ 100x kleiner als der globale Speicherzugriff. Hier geht es vor allem darum, den Bankenkonflikt zu vermeiden.

Sie möchten vielleicht die folgenden Links für weitere Informationen lesen.

https://devblogs.nvidia.com/parallelforall/how-access-global-memory-efficiently-cuda-c-kernels/

https://devblogs.nvidia.com/parallelforall/using-shared-memory-cuda-cc/

http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#memory-hierarchy

http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#maximize-memory-throughput

http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#device-memory-spaces

+3

Ich glaube, dass Ihre Aussagen im Allgemeinen richtig sind, aber ich vermute auch, die Frage ist allgemein gefragt, wie viele Lesevorgänge können im Flug sein ("in der Pipeline"). AFAIK für globalen Speicher Dies ist nirgends dokumentiert und ist weitgehend eine Funktion der LD/ST-Einheit und der damit verbundenen Warteschlangen. Für Codes, die gut geschrieben sind (dh das Speichersubsystem effizient nutzen), sollte es nie ein Problem sein - es gibt immer mehr Kapazität in der LD/ST-Einheit, um Transaktionsanforderungen zu akzeptieren als solche, die sinnvollerweise aus einem einzigen Thread erzeugt werden können. Kette. –

+0

@RobertCrovella Ich denke er fragt, wie viele Lese * in einem Thread * im Flug sein kann. Das muss 1 sein, oder? – kangshiyin

+4

Ein Thread kann mehrere Lesevorgänge ausführen (in separaten Anweisungen im Anweisungsdatenstrom). Mehrere Lesevorgänge von einem einzelnen Thread können im Flug sein. Eine Leseanfrage * an sich * hält den Thread nicht an. Nur wenn die Ergebnisse dieser Leseoperation für eine zukünftige Operation erforderlich sind, wird sie angehalten (wenn die gelesenen Daten nicht verfügbar sind). Der Compiler ist sich dessen bewusst und wird versuchen, Lesevorgänge zu planen, bevor die Daten tatsächlich benötigt werden. In solchen Szenarien können mehrere Lesevorgänge (von einem einzelnen Thread oder Warp) im Flug ausgeführt werden. –