wake-up-neo.com

Was ist der Zweck der Verwendung mehrerer "Arch" -Flaggen im NVCC-Compiler von Nvidia?

Ich habe mich kürzlich damit beschäftigt, wie NVCC CUDA-Gerätecode für verschiedene Berechnungsarchitekturen kompiliert.

Soweit ich weiß, ist bei der NVCC-Option -gencode "Arch" die von der Anwendung des Programmierers erforderliche Mindestrechenarchitektur und auch die Mindest-Rechenarchitektur für Geräte, für die der JIT-Compiler von NVCC PTX-Code kompiliert. 

Ich verstehe auch, dass der Parameter "Code" von -gencode die Berechnungsarchitektur ist, für die NVCC die Anwendung vollständig kompiliert, sodass keine JIT-Kompilierung erforderlich ist.

Nach der Inspektion verschiedener CUDA-Projekt-Makefiles habe ich regelmäßig Folgendes festgestellt:

-gencode Arch=compute_20,code=sm_20
-gencode Arch=compute_20,code=sm_21
-gencode Arch=compute_21,code=sm_21

und nach einiger Lektüre stellte ich fest, dass mehrere Gerätearchitekturen in einer einzigen Binärdatei kompiliert werden können - in diesem Fall sm_20, sm_21.

Meine Fragen sind warum sind so viele Arch/Code-Paare notwendig? Werden alle Werte von "Arch" oben verwendet?

was ist der Unterschied zwischen dem und sagen:

-Arch compute_20
-code sm_20
-code sm_21

Ist die früheste virtuelle Architektur in den Feldern "Arch" automatisch ausgewählt oder gibt es ein anderes obskures Verhalten?

Gibt es ein anderes Kompilierungs- und Laufzeitverhalten, das ich beachten sollte?

Ich habe das Handbuch gelesen, http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-compilation und bin mir immer noch nicht klar, was beim Kompilieren passiert oder Laufzeit.

29

Der Code-Kompilierungsfluss sieht ungefähr so ​​aus:

CUDA C/C++ - Gerätecodequelle -> PTX -> SASS

Die virtuelle Architektur (z. B. compute_20, was auch immer durch -Arch compute... angegeben ist) bestimmt, welcher Typ von PTX-Code generiert wird. Die zusätzlichen Schalter (z. B. -code sm_21) bestimmen, welcher Typ von SASS-Code erzeugt wird. SASS ist tatsächlich ein ausführbarer Objektcode für eine GPU (Maschinensprache). Eine ausführbare Datei kann mehrere Versionen von SASS und/oder PTX enthalten, und es gibt einen Laufzeitlade-Mechanismus, der die geeigneten Versionen basierend auf der tatsächlich verwendeten GPU auswählt.

Wie Sie wissen, ist JIT-Compile eine der praktischen Funktionen des GPU-Betriebs. Die JIT-Kompilierung wird vom GPU-Treiber ausgeführt (es ist keine Installation des CUDA-Toolkits erforderlich), wann immer ein geeigneter PTX-Code verfügbar ist, ein geeigneter SASS-Code jedoch nicht.

Ein Vorteil des Einbaus mehrerer virtueller Architekturen (d. H. Mehrerer Versionen von PTX) ist die Kompatibilität der ausführbaren Dateien mit einer größeren Anzahl von Ziel-GPU-Geräten (obwohl einige Geräte möglicherweise eine JIT-Kompilierung auslösen, um das erforderliche SASS zu erstellen).

Ein Vorteil des Einbaus mehrerer "realer GPU-Ziele" (d. H. Mehrerer SASS-Versionen) besteht darin, dass Sie den JIT-Kompilierungsschritt vermeiden können, wenn eines dieser Zielgeräte vorhanden ist.

Wenn Sie einen falschen Satz von Optionen angeben, können Sie eine ausführbare Datei erstellen, die auf einer bestimmten GPU nicht (richtig) ausgeführt wird.

Ein möglicher Nachteil bei der Festlegung vieler dieser Optionen ist das Aufblähen der Codegröße. Ein weiterer möglicher Nachteil ist die Kompilierzeit, die normalerweise länger ist, wenn Sie mehr Optionen angeben.

Es ist auch möglich, ausführbare Dateien zu erstellen, die kein PTX enthalten, was für diejenigen interessant sein könnte, die versuchen, ihre IP zu verschleiern.

Das Erstellen eines für JIT geeigneten PTX sollte durch Festlegen einer virtuellen Architektur für den Schalter code erfolgen.

37
Robert Crovella

Der Zweck mehrerer -Arch-Flags besteht darin, das __CUDA_Arch__-Makro für die bedingte Kompilierung (dh Verwendung von #ifdef) unterschiedlich optimierter Codepfade zu verwenden.

Siehe hier: http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#virtual-architecture-identification-macro

1