Parallel Thread Execution

Parallel Thread Execution (PTX oder NVPTX[1]) ist eine Befehlssatzarchitektur und virtuelle Maschine für die Ausführung von parallelen Threads, die in der CUDA-Programmierung von Nvidia verwendet wird. Der NVCC-Kompilierer übersetzt Code, der in CUDA, einer C++-ähnlichen Sprache, geschrieben wurde, in PTX-Anweisungen (eine Maschinensprache dargestellt als ASCII-Text). Der Grafiktreiber enthält einen Kompilierer, der die PTX-Anweisungen in den ausführbaren Binärcode übersetzt[2], der auf den Prozessorkernen der Nvidia-GPUs ausgeführt werden kann. Die GNU-Compiler-Kollektion verfügt auch über grundlegende Fähigkeiten zur PTX-Erzeugung im Zusammenhang mit OpenMP.[3] Inline-PTX-Assembly kann in CUDA verwendet werden.[4]

PTX verwendet einen beliebig großen Registersatz; die Ausgabe des Compilers erfolgt fast ausschließlich in Form von Einzelzuweisungen, wobei sich aufeinanderfolgende Zeilen im Allgemeinen auf aufeinanderfolgende Register beziehen. Programme beginnen mit Deklarationen der Form

.reg .u32 %r<335>;            // deklariere 335 Register %r0, %r1, ..., %r334 vom Typ vorzeichenlosem 32-Bit Integer

Es handelt sich um eine Assemblersprache mit drei Argumenten. Fast alle Befehle geben ausdrücklich den Datentyp (in Form von Vorzeichen und Breite) an, mit dem sie arbeiten. Registernamen wird ein %-Zeichen vorangestellt und Konstanten sind Literale z. B.:

shr.u64 %rd14, %rd12, 32;     // schiebe einen vorzeichenlosen 64-Bit Integer aus %rd12 nach rechts um 32 Positionen, Ergebnis in %rd14
cvt.u64.u32 %rd142, %r112;    // konvertiere einen vorzeichenlosen 32-Bit Integer zu 64-Bit

Es gibt Prädikatsregister, aber kompilierter Code im Shader-Modell 1.0 verwendet diese nur in Verbindung mit Verzweigungsbefehlen; die bedingte Verzweigung ist

@%p14 bra $label;             // gehe zu $label

Die Anweisung setp.cc.type setzt ein Prädikatsregister auf das Ergebnis des Vergleichs zweier Register des entsprechenden Typs. Es gibt auch eine Anweisung set, wobei set.le.u32.u64 %r101, %rd12, %rd28 das 32-Bit-Register %r101 zu 0xffffffff setzt, wenn das 64-Bit-Register %rd12 kleiner oder gleich dem 64-Bit-Register %rd28 ist. Andernfalls wird %r101 zu 0x00000000 gesetzt.

Es gibt ein paar vordefinierte Bezeichner, die Pseudoregister bezeichnen. Unter anderem enthalten %tid, %ntid, %ctaid, und %nctaid Thread-Indizes, Block-Dimensionen, Block-Indizes und Grid-Dimensionen.[5]

Zustandsbereiche

[Bearbeiten | Quelltext bearbeiten]

Die Befehle Laden (ld) und Speichern (st) beziehen sich auf einen von mehreren verschiedenen Zustandsbereichen, z. B. ld.param. Es gibt acht Zustandsbereiche:[5]

  • .reg : Register
  • .sreg : spezielle, plattformspezifische Register
  • .const : geteilter, nur lesender Speicher
  • .global : globaler Speicher von allen Threads
  • .local : thread-lokaler Speicher
  • .param : Parameter, die an der Kernel übergeben werden
  • .shared : gemeinsamer Speicher von Threads im selben Block
  • .tex : globaler Texturspeicher (veraltet)

Geteilter Speicher wird in der PTX-Datei wie folgt deklariert:

.shared .align 8 .b8 pbatch_cache[15744]; // definiere 15.744 Bytes, ausgerichtet an 8-Byte-Grenzen

Das Schreiben von Kerneln in PTX erfordert die explizite Registrierung von PTX-Modulen über die CUDA-Treiber-API, was in der Regel umständlicher ist als die Verwendung der CUDA-Runtime-API und des CUDA-Compilers nvcc von Nvidia. Das GPU Ocelot-Projekt bot eine API zur Registrierung von PTX-Modulen neben CUDA-Runtime-API-Kernelaufrufen, allerdings wird GPU Ocelot nicht mehr aktiv weiterentwickelt.[6]

  • Standard Portable Intermediate Representation (SPIR)
  • CUDA binary (cubin) – a type of fat binary

Einzelnachweise

[Bearbeiten | Quelltext bearbeiten]
  1. User Guide for NVPTX Back-end — LLVM 7 documentation. In: llvm.org.
  2. CUDA Binary Utilities. In: docs.nvidia.com. Abgerufen am 19. Oktober 2019 (amerikanisches Englisch).
  3. nvptx. In: GCC Wiki.
  4. Inline PTX Assembly in CUDA. In: docs.nvidia.com. Abgerufen am 3. November 2019 (amerikanisches Englisch).
  5. a b PTX ISA Version 2.3.
  6. GPUOCelot: A dynamic compilation framework for PTX. In: github.com.